From David Callu, "Problem:
osgText::Text and osgText::Text3D use the same font file. The first really load the file and obtain an osgText::Font object, the second use the cache created during the first load of the font file, and so obtain an osgText::Font object instead of osgText::Font3D object. To obtain an osgText::Font3D object, osgText::Text3D call osgDB::readObjectFile(...) with an option to specify the plugin we want an osgText::Font3D instead of osgText::Font. Generalised Problem: In osgDB::Registry, loaded file cache is referenced by the name of this file, so if I load a file with some options, and the cache already contain object for this filename, I obtain an object potentially not loaded with my options. Behaviours: Cache management is delegate to osgDB::Registry, but cache coherence (load a file with option then reuse it, deactivate the cache when load a specific file or don't cached the loaded file) is user's responsibility. Text3D solution: Postfix the font file name by .text3d or something similar and then have the freetype plugin return osgText::Font3D when it detects this. This operation is done by osgText::readFont3DFile() which unsure the filename have .text3d as extension. This is totaly transparent for user, and backward compatible. BTW, I fix the bug about the Normal of 3D text. Currently, the front and wall face have the same normal (0,0,1) in the Text3D object coordinate. Now the wall face have its own normal array computed by the plugin. BTW 2, I implement - void Text3D::accept(osg::Drawable::ConstAttributeFunctor& af) const - void Text3D::accept(osg::PrimitiveFunctor& pf) const so now statistics are well reported. "
This commit is contained in:
parent
e7c4cda108
commit
9643c15346
@ -1,13 +1,13 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
@ -31,7 +31,7 @@ class Font3D;
|
||||
class Text3D;
|
||||
|
||||
/** Read a font from specified file. The filename may contain a path.
|
||||
* It will search for the font file in the following places in this order:
|
||||
* It will search for the font file in the following places in this order:
|
||||
* - In the current directory
|
||||
* - All paths defined in OSG_FILE_PATH or OSGFILEPATH environment variable
|
||||
* - Filename with path stripped: In the current directory
|
||||
@ -45,7 +45,7 @@ class Text3D;
|
||||
* - Other OS: In /usr/share/fonts/ttf
|
||||
* - Other OS: In /usr/share/fonts/ttf/western
|
||||
* - Other OS: In /usr/share/fonts/ttf/decoratives
|
||||
*
|
||||
*
|
||||
* If the given file could not be found, the path part will be stripped and
|
||||
* the file will be searched again in the OS specific directories.
|
||||
*/
|
||||
@ -67,7 +67,7 @@ class OSGTEXT_EXPORT Font3D : public osg::Object
|
||||
{
|
||||
// declare the interface to a font.
|
||||
public:
|
||||
|
||||
|
||||
// forward declare nested classes.
|
||||
class Glyph3D;
|
||||
class Font3DImplementation;
|
||||
@ -92,13 +92,13 @@ public:
|
||||
|
||||
/** Get a Glyph for specified charcode, and the font size nearest to the current font size hint.*/
|
||||
virtual Glyph3D* getGlyph(unsigned int charcode);
|
||||
|
||||
|
||||
/** Return true if this font provides vertical alignments and spacing or glyphs.*/
|
||||
virtual bool hasVertical() const;
|
||||
|
||||
/** Return the scale to apply on the glyph to have a charactere size equal to 1 */
|
||||
virtual float getScale() const { return _implementation->getScale(); };
|
||||
|
||||
|
||||
// make Text a friend to allow it add and remove its entry in the Font's _textList.
|
||||
friend class Font3DImplementation;
|
||||
|
||||
@ -109,16 +109,16 @@ public:
|
||||
|
||||
/** Set whether to use a mutex to ensure ref() and unref() */
|
||||
virtual void setThreadSafeRefUnref(bool threadSafe);
|
||||
|
||||
|
||||
typedef OpenThreads::Mutex Font3DMutex;
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~Font3D();
|
||||
|
||||
|
||||
// void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph* glyph);
|
||||
void addGlyph(unsigned int charcode, Glyph3D* glyph);
|
||||
|
||||
|
||||
// current active size of font
|
||||
unsigned int _depth;
|
||||
unsigned int _width;
|
||||
@ -127,22 +127,22 @@ protected:
|
||||
// float _marginRatio;
|
||||
|
||||
typedef std::map<char, osg::ref_ptr<Glyph3D> > Glyph3DMap;
|
||||
Glyph3DMap _glyph3DMap;
|
||||
|
||||
Glyph3DMap _glyph3DMap;
|
||||
|
||||
osg::ref_ptr<Font3DImplementation> _implementation;
|
||||
|
||||
|
||||
|
||||
// declare the nested classes.
|
||||
public:
|
||||
|
||||
class Font3DImplementation : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
Font3DImplementation():
|
||||
osg::Referenced(true),
|
||||
_facade(0) {}
|
||||
|
||||
|
||||
virtual std::string getFileName() const = 0;
|
||||
|
||||
/** Get a Glyph for specified charcode, and the font size nearest to the current font size hint.*/
|
||||
@ -153,20 +153,20 @@ public:
|
||||
|
||||
/** Return true if this font provides vertical alignments and spacing or glyphs.*/
|
||||
virtual bool hasVertical() const = 0;
|
||||
|
||||
|
||||
virtual float getScale() const = 0;
|
||||
|
||||
|
||||
void setFontWidth(unsigned int width) { _facade->_width = width; }
|
||||
|
||||
void setFontHeight(unsigned int height) { _facade->_height = height; }
|
||||
|
||||
|
||||
void setFontDepth(unsigned int depth) { _facade->_depth = depth; }
|
||||
|
||||
|
||||
// void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph3D* glyph)
|
||||
// {
|
||||
// _facade->addGlyph(width, height, charcode, glyph);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// void addGlyph(unsigned int charcode, Glyph3D* glyph)
|
||||
// {
|
||||
// _facade->addGlyph(charcode, glyph);
|
||||
@ -181,26 +181,26 @@ public:
|
||||
|
||||
Glyph3D(unsigned int glyphCode):
|
||||
osg::Referenced(true),
|
||||
_glyphCode(glyphCode),
|
||||
_glyphCode(glyphCode),
|
||||
_horizontalBearing(0,0),
|
||||
_horizontalAdvance(0),
|
||||
_verticalBearing(0,0),
|
||||
_verticalAdvance(0)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
/** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
|
||||
// virtual int compare(const osg::StateAttribute& rhs) const;
|
||||
//
|
||||
//
|
||||
// virtual void apply(osg::State& state) const;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
unsigned int getGlyphCode() const { return _glyphCode; }
|
||||
|
||||
|
||||
void setHorizontalBearing(const osg::Vec2& bearing) { _horizontalBearing=bearing; }
|
||||
const osg::Vec2 & getHorizontalBearing() const { return _horizontalBearing; }
|
||||
|
||||
|
||||
void setHorizontalAdvance(float advance) { _horizontalAdvance=advance; }
|
||||
float getHorizontalAdvance() const { return _horizontalAdvance; }
|
||||
|
||||
@ -209,42 +209,44 @@ public:
|
||||
|
||||
void setVerticalAdvance(float advance) { _verticalAdvance=advance; }
|
||||
float getVerticalAdvance() const { return _verticalAdvance; }
|
||||
|
||||
|
||||
void setBoundingBox(osg::BoundingBox & bb) { _bb=bb; }
|
||||
const osg::BoundingBox & getBoundingBox() const { return _bb; }
|
||||
|
||||
|
||||
|
||||
|
||||
/** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/
|
||||
virtual void setThreadSafeRefUnref(bool threadSafe);
|
||||
|
||||
|
||||
|
||||
/** Get the PrimitiveSetList for the front face. */
|
||||
osg::Geometry::PrimitiveSetList & getFrontPrimitiveSetList() { return _frontPrimitiveSetList; }
|
||||
/** Get the PrimitiveSetList for the wall face. */
|
||||
osg::Geometry::PrimitiveSetList & getWallPrimitiveSetList() { return _wallPrimitiveSetList; }
|
||||
/** Get et the PrimitiveSetList for the back face. */
|
||||
osg::Geometry::PrimitiveSetList & getBackPrimitiveSetList() { return _backPrimitiveSetList; }
|
||||
|
||||
|
||||
/** Set the VertexArray of the glyph. */
|
||||
void setVertexArray(osg::Vec3Array * va) { _vertexArray = va; }
|
||||
/** Get the VertexArray of the glyph. */
|
||||
osg::Vec3Array * getVertexArray() { return _vertexArray.get(); }
|
||||
/** Set the VertexArray of the glyph. */
|
||||
void setNormalArray(osg::Vec3Array * na) { _normalArray = na; }
|
||||
/** Get the NormalArray for the wall face. */
|
||||
osg::Vec3Array * getNormalArray() { return _normalArray.get(); }
|
||||
|
||||
|
||||
float getHorizontalWidth() { return (-_horizontalBearing.x() + _horizontalAdvance); }
|
||||
float getHorizontalHeight() { return (-_horizontalBearing.y() + _bb.yMax()); }
|
||||
float getVerticalWidth() { return (-_verticalBearing.x() + _bb.xMax()); }
|
||||
float getVerticalHeight() { return (-_verticalBearing.y() + _verticalAdvance); }
|
||||
|
||||
|
||||
void setWidth(float width) { _width = width; }
|
||||
float getWidth() { return _width; }
|
||||
|
||||
|
||||
void setHeight(float height) { _height = height; }
|
||||
float getHeight() { return _height; }
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
virtual ~Glyph3D() {}
|
||||
|
||||
unsigned int _glyphCode;
|
||||
@ -255,21 +257,21 @@ public:
|
||||
osg::Vec2 _verticalBearing;
|
||||
float _verticalAdvance;
|
||||
|
||||
osg::BoundingBox _bb;
|
||||
osg::BoundingBox _bb;
|
||||
// osg::Vec2 _advance;
|
||||
|
||||
|
||||
float _width;
|
||||
float _height;
|
||||
|
||||
|
||||
|
||||
|
||||
osg::ref_ptr<osg::Vec3Array> _vertexArray;
|
||||
osg::ref_ptr<osg::Vec3Array> _normalArray;
|
||||
|
||||
|
||||
osg::Geometry::PrimitiveSetList _frontPrimitiveSetList;
|
||||
osg::Geometry::PrimitiveSetList _wallPrimitiveSetList;
|
||||
osg::Geometry::PrimitiveSetList _backPrimitiveSetList;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
@ -30,7 +30,7 @@ public:
|
||||
* PER_FACE : render all front face with the default StateSet
|
||||
* all wall face with the wall StateSet
|
||||
* all back face with the back StateSet (back face of the character, no the OpenGL back face)
|
||||
*
|
||||
*
|
||||
* PER_GLYPH : render all Charactere with the default StateSet
|
||||
*/
|
||||
enum RenderMode
|
||||
@ -38,7 +38,7 @@ public:
|
||||
PER_FACE,
|
||||
PER_GLYPH
|
||||
};
|
||||
|
||||
|
||||
Text3D();
|
||||
Text3D(const Text3D& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
@ -48,7 +48,7 @@ public:
|
||||
float getCharacterDepth() const { return _characterDepth; }
|
||||
/** Set the Charactere Depth of text. */
|
||||
void setCharacterDepth(float characterDepth) { _characterDepth = characterDepth; computeGlyphRepresentation(); }
|
||||
|
||||
|
||||
/** Get the render mode used to render the text. */
|
||||
RenderMode getRenderMode() const { return _renderMode; }
|
||||
/** Set the render mode used to render the text. */
|
||||
@ -57,10 +57,10 @@ public:
|
||||
// /** Get the wall StateSet */
|
||||
// osg::StateSet * getWallStateSet() { return _wallStateSet.get(); }
|
||||
// /** Get or create the wall StateSet */
|
||||
// osg::StateSet * getOrCreateWallStateSet()
|
||||
// {
|
||||
// if (_wallStateSet.valid() == false) _wallStateSet = new osg::StateSet;
|
||||
// return _wallStateSet.get();
|
||||
// osg::StateSet * getOrCreateWallStateSet()
|
||||
// {
|
||||
// if (_wallStateSet.valid() == false) _wallStateSet = new osg::StateSet;
|
||||
// return _wallStateSet.get();
|
||||
// }
|
||||
// /** Set the wall StateSet */
|
||||
// void setWallStateSet(osg::StateSet * wallStateSet) { _wallStateSet = wallStateSet; }
|
||||
@ -71,9 +71,9 @@ public:
|
||||
// osg::StateSet * getOrCreateBackStateSet() { if (_backStateSet.valid() == false) _backStateSet = new osg::StateSet; return _backStateSet.get(); }
|
||||
// /** Set the back StateSet */
|
||||
// void setBackStateSet(osg::StateSet * backStateSet) { _backStateSet = backStateSet; }
|
||||
//
|
||||
|
||||
/** Set the Font to use to render the text.
|
||||
//
|
||||
|
||||
/** 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<Font3D>(font)); };
|
||||
|
||||
@ -86,12 +86,12 @@ public:
|
||||
* See the osgText::readFontFile function for how the font file will be located. */
|
||||
void setFont(const std::string& fontfile);
|
||||
|
||||
/** Get the font. Return 0 if default is being used.*/
|
||||
/** Get the font. Return 0 if default is being used.*/
|
||||
const Font3D* getFont() const { return _font.get(); }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Draw the text.*/
|
||||
virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
|
||||
|
||||
@ -102,13 +102,13 @@ public:
|
||||
virtual bool supports(const osg::Drawable::ConstAttributeFunctor&) const { return false; }
|
||||
|
||||
/** accept an ConstAttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/
|
||||
// virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const;
|
||||
virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const;
|
||||
|
||||
/** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/
|
||||
virtual bool supports(const osg::PrimitiveFunctor&) const { return false; }
|
||||
|
||||
/** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/
|
||||
// virtual void accept(osg::PrimitiveFunctor& pf) const;
|
||||
virtual void accept(osg::PrimitiveFunctor& pf) const;
|
||||
|
||||
|
||||
/** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/
|
||||
@ -122,7 +122,7 @@ public:
|
||||
* for all graphics contexts. */
|
||||
virtual void releaseGLObjects(osg::State* state=0) const;
|
||||
|
||||
// // make Font a friend to allow it set the _font to 0 if the font is
|
||||
// // make Font a friend to allow it set the _font to 0 if the font is
|
||||
// // forcefully unloaded.
|
||||
friend class Font3D;
|
||||
|
||||
@ -131,8 +131,8 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~Text3D() {}
|
||||
|
||||
virtual ~Text3D() {}
|
||||
|
||||
void renderPerGlyph(osg::State & state) const;
|
||||
void renderPerFace(osg::State & state) const;
|
||||
|
||||
@ -140,28 +140,28 @@ protected:
|
||||
|
||||
void computeGlyphRepresentation();
|
||||
void computePositions(unsigned int contextID) const;
|
||||
|
||||
|
||||
// ** glyph and other information to render the glyph
|
||||
struct GlyphRenderInfo
|
||||
{
|
||||
GlyphRenderInfo(Font3D::Glyph3D * glyph, osg::Vec3 & pos) :
|
||||
_glyph(glyph), _position(pos) {}
|
||||
|
||||
|
||||
osg::ref_ptr<Font3D::Glyph3D> _glyph;
|
||||
osg::Vec3 _position;
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<GlyphRenderInfo> LineRenderInfo;
|
||||
typedef std::vector<LineRenderInfo> TextRenderInfo;
|
||||
|
||||
typedef std::vector<LineRenderInfo> TextRenderInfo;
|
||||
|
||||
TextRenderInfo _textRenderInfo;
|
||||
|
||||
osg::ref_ptr<Font3D> _font;
|
||||
|
||||
float _characterDepth;
|
||||
|
||||
|
||||
RenderMode _renderMode;
|
||||
|
||||
|
||||
osg::ref_ptr<osg::StateSet> _wallStateSet;
|
||||
osg::ref_ptr<osg::StateSet> _backStateSet;
|
||||
};
|
||||
|
@ -318,8 +318,9 @@ Registry::Registry()
|
||||
addFileExtensionAlias("cff", "freetype"); // OpenType
|
||||
addFileExtensionAlias("cef", "freetype"); // OpenType
|
||||
addFileExtensionAlias("fon", "freetype"); // Windows bitmap fonts
|
||||
addFileExtensionAlias("fnt", "freetype"); // Windows bitmap fonts
|
||||
|
||||
addFileExtensionAlias("fnt", "freetype"); // Windows bitmap fonts
|
||||
addFileExtensionAlias("text3d", "freetype"); // use 3D Font instead of 2D Font
|
||||
|
||||
// wont't add type1 and type2 until resolve extension collision with Performer binary and ascii files.
|
||||
// addFileExtensionAlias("pfb", "freetype"); // type1 binary
|
||||
// addFileExtensionAlias("pfa", "freetype"); // type2 ascii
|
||||
|
@ -1,13 +1,13 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
@ -20,13 +20,13 @@
|
||||
|
||||
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Notify>
|
||||
#include <osg/Notify>
|
||||
#include <osgDB/WriteFile>
|
||||
#include <osgUtil/SmoothingVisitor>
|
||||
#include <osgUtil/Tessellator>
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include <freetype/ftoutln.h>
|
||||
@ -173,7 +173,7 @@ int conicTo( const FT_Vector* control,const FT_Vector* to, void* user )
|
||||
int cubicTo( const FT_Vector* control1,const FT_Vector* control2,const FT_Vector* to, void* user )
|
||||
{
|
||||
Char3DInfo* char3d = (Char3DInfo*)user;
|
||||
char3d->cubicTo(
|
||||
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)) );
|
||||
@ -220,7 +220,7 @@ void FreeTypeFont3D::init()
|
||||
return;
|
||||
}
|
||||
|
||||
FT_Set_Char_Size( _face, 64*64, 64*64, 600, 600);
|
||||
FT_Set_Char_Size( _face, 64*64, 64*64, 600, 600);
|
||||
|
||||
int glyphIndex = FT_Get_Char_Index( _face, 'M' );
|
||||
_error = FT_Load_Glyph( _face, glyphIndex, FT_LOAD_DEFAULT );
|
||||
@ -290,7 +290,7 @@ FreeTypeFont3D::~FreeTypeFont3D()
|
||||
// remove myself from the local registry to ensure that
|
||||
// not dangling pointers remain
|
||||
freeTypeLibrary->removeFont3DImplmentation(this);
|
||||
|
||||
|
||||
// free the freetype font face itself
|
||||
FT_Done_Face(_face);
|
||||
_face = 0;
|
||||
@ -308,12 +308,12 @@ FreeTypeFont3D::~FreeTypeFont3D()
|
||||
|
||||
osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being
|
||||
// returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct
|
||||
// values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect.
|
||||
// GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being
|
||||
// returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct
|
||||
// values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect.
|
||||
// Microsoft uses a private field for its symbol fonts
|
||||
//
|
||||
unsigned int charindex = charcode;
|
||||
@ -336,7 +336,7 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode)
|
||||
osg::notify(osg::WARN) << "FreeTypeFont3D::getGlyph : not a vector font" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ** init FreeType to describe the glyph
|
||||
Char3DInfo char3d;
|
||||
|
||||
@ -348,7 +348,7 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode)
|
||||
funcs.move_to = (FT_Outline_MoveToFunc)&moveTo;
|
||||
funcs.shift = 0;
|
||||
funcs.delta = 0;
|
||||
|
||||
|
||||
// ** record description
|
||||
FT_Error _error = FT_Outline_Decompose(&outline, &funcs, &char3d);
|
||||
if (_error)
|
||||
@ -356,74 +356,74 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode)
|
||||
osg::notify(osg::WARN) << "FreeTypeFont3D::getGlyph : - outline decompose failed ..." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ** create geometry for each part of the glyph
|
||||
osg::ref_ptr<osg::Geometry> frontGeo(new osg::Geometry);
|
||||
frontGeo->setVertexArray(char3d.get()->getVertexArray());
|
||||
frontGeo->setPrimitiveSetList(char3d.get()->getPrimitiveSetList());
|
||||
|
||||
|
||||
osg::ref_ptr<osg::Geometry> wallGeo(new osg::Geometry);
|
||||
wallGeo->setVertexArray(frontGeo->getVertexArray());
|
||||
|
||||
|
||||
osg::ref_ptr<osg::Geometry> backGeo(new osg::Geometry);
|
||||
backGeo->setVertexArray(frontGeo->getVertexArray());
|
||||
|
||||
|
||||
|
||||
// ** for conveniance.
|
||||
|
||||
|
||||
|
||||
// ** for convenience.
|
||||
osg::Vec3Array * vertices = char3d._verts.get();
|
||||
|
||||
|
||||
|
||||
// ** duplicate the vertex for the back face
|
||||
|
||||
|
||||
|
||||
// ** duplicate the vertex for the back face
|
||||
// ** with a depth equal to the font depth
|
||||
std::size_t len = vertices->size();
|
||||
std::size_t dlen = len * 2;
|
||||
|
||||
|
||||
vertices->reserve(dlen);
|
||||
|
||||
|
||||
osg::Vec3Array::iterator begin = vertices->begin();
|
||||
osg::Vec3Array::iterator it = vertices->begin();
|
||||
|
||||
|
||||
for (std::size_t i = 0; i != len; ++i, ++it)
|
||||
vertices->push_back(*it);
|
||||
// std::copy(begin, begin + len, begin + len + 1); TOCHECK
|
||||
|
||||
|
||||
|
||||
|
||||
// ** and decal new vertices
|
||||
unsigned int depth = _facade->getFontDepth();
|
||||
for (std::size_t i = len; i != dlen; ++i)
|
||||
{
|
||||
(*vertices)[i].z() -= depth;
|
||||
}
|
||||
|
||||
|
||||
osg::Vec3Array::iterator end;
|
||||
|
||||
|
||||
// ** create wall and back face from the front polygon
|
||||
// ** then accumulate them in the apropriate geometry wallGeo and backGeo
|
||||
// ** then accumulate them in the appropriate geometry wallGeo and backGeo
|
||||
for (std::size_t i=0; i < frontGeo->getNumPrimitiveSets(); ++i)
|
||||
{
|
||||
// ** get the front polygon
|
||||
osg::ref_ptr<osg::DrawArrays> daFront(dynamic_cast<osg::DrawArrays*>(frontGeo->getPrimitiveSet(i)));
|
||||
unsigned int idx = daFront->getFirst();
|
||||
unsigned int cnt = daFront->getCount();
|
||||
|
||||
|
||||
// ** reverse vertices to draw the front face in the CCW
|
||||
std::reverse(begin + idx, begin + idx + cnt);
|
||||
|
||||
|
||||
// ** create the back polygon
|
||||
osg::ref_ptr<osg::DrawArrays> daBack(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, idx + len, cnt));
|
||||
backGeo->addPrimitiveSet(daBack.get());
|
||||
|
||||
|
||||
|
||||
|
||||
// ** create the wall triangle strip
|
||||
osg::ref_ptr<osg::DrawElementsUInt> deWall(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP));
|
||||
osg::ref_ptr<osg::DrawElementsUInt> deWall(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP));
|
||||
wallGeo->addPrimitiveSet(deWall.get());
|
||||
|
||||
|
||||
// ** link triangle strip
|
||||
deWall->push_back(idx + len);
|
||||
for (unsigned int j = 1; j < cnt; ++j)
|
||||
{
|
||||
{
|
||||
deWall->push_back(idx + cnt - j);
|
||||
deWall->push_back(idx + len + j);
|
||||
}
|
||||
@ -439,7 +439,7 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode)
|
||||
ts.setTessellationType(osgUtil::Tessellator::TESS_TYPE_GEOMETRY);
|
||||
ts.retessellatePolygons(*frontGeo);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
osgUtil::Tessellator ts;
|
||||
ts.setWindingType(osgUtil::Tessellator::TESS_WINDING_POSITIVE);
|
||||
@ -454,17 +454,18 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode)
|
||||
geode->addDrawable(wallGeo.get());
|
||||
geode->accept(sm);
|
||||
}
|
||||
|
||||
// ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list
|
||||
|
||||
// ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list
|
||||
osgText::Font3D::Glyph3D * glyph3D = new osgText::Font3D::Glyph3D(charcode);
|
||||
|
||||
glyph3D->setVertexArray(dynamic_cast<osg::Vec3Array*>(frontGeo->getVertexArray()));
|
||||
|
||||
glyph3D->setNormalArray(dynamic_cast<osg::Vec3Array*>(wallGeo->getNormalArray()));
|
||||
|
||||
glyph3D->getFrontPrimitiveSetList() = frontGeo->getPrimitiveSetList();
|
||||
glyph3D->getWallPrimitiveSetList() = wallGeo->getPrimitiveSetList();
|
||||
glyph3D->getBackPrimitiveSetList() = backGeo->getPrimitiveSetList();
|
||||
|
||||
|
||||
|
||||
FT_Glyph_Metrics* metrics = &(_face->glyph->metrics);
|
||||
|
||||
glyph3D->setHorizontalBearing(osg::Vec2((float)metrics->horiBearingX/64.0f,(float)(metrics->horiBearingY-metrics->height)/64.0f)); // bottom left.
|
||||
@ -475,7 +476,7 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode)
|
||||
glyph3D->setWidth((float)metrics->width / 64.0f);
|
||||
glyph3D->setHeight((float)metrics->height / 64.0f);
|
||||
|
||||
|
||||
|
||||
FT_BBox ftbb;
|
||||
FT_Outline_Get_BBox(&outline, &ftbb);
|
||||
|
||||
@ -483,11 +484,11 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode)
|
||||
long xmax = ft_ceiling( ftbb.xMax );
|
||||
long ymin = ft_floor( ftbb.yMin );
|
||||
long ymax = ft_ceiling( ftbb.yMax );
|
||||
|
||||
|
||||
osg::BoundingBox bb(xmin / 64.0f, ymin / 64.0f, 0.0f, xmax / 64.0f, ymax / 64.0f, 0.0f);
|
||||
|
||||
|
||||
glyph3D->setBoundingBox(bb);
|
||||
|
||||
|
||||
return glyph3D;
|
||||
}
|
||||
|
||||
@ -500,8 +501,8 @@ osg::Vec2 FreeTypeFont3D::getKerning(unsigned int leftcharcode,unsigned int righ
|
||||
// convert character code to glyph index
|
||||
FT_UInt left = FT_Get_Char_Index( _face, leftcharcode );
|
||||
FT_UInt right = FT_Get_Char_Index( _face, rightcharcode );
|
||||
|
||||
// get the kerning distances.
|
||||
|
||||
// get the kerning distances.
|
||||
FT_Vector kerning;
|
||||
|
||||
FT_Error error = FT_Get_Kerning( _face, // handle to face object
|
||||
@ -524,7 +525,7 @@ bool FreeTypeFont3D::hasVertical() const
|
||||
return FT_HAS_VERTICAL(_face)!=0;
|
||||
}
|
||||
|
||||
float FreeTypeFont3D::getScale() const
|
||||
{
|
||||
return _scale;
|
||||
float FreeTypeFont3D::getScale() const
|
||||
{
|
||||
return _scale;
|
||||
}
|
||||
|
@ -17,14 +17,15 @@ class ReaderWriterFreeType : public osgDB::ReaderWriter
|
||||
supportsExtension("cid","Postscript CID-Fonts format");
|
||||
supportsExtension("cff","OpenType format");
|
||||
supportsExtension("cef","OpenType format");
|
||||
supportsExtension("fon","Windows bitmap fonts format");
|
||||
supportsExtension("fon","Windows bitmap fonts format");
|
||||
supportsExtension("fnt","Windows bitmap fonts format");
|
||||
supportsExtension("text3d","use 3D Font instead of 2D Font");
|
||||
|
||||
supportsOption("monochrome","Select monochrome font.");
|
||||
}
|
||||
|
||||
|
||||
virtual const char* className() const { return "FreeType Font Reader/Writer"; }
|
||||
|
||||
|
||||
static unsigned int getFlags(const osgDB::ReaderWriter::Options* options)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
@ -32,26 +33,40 @@ class ReaderWriterFreeType : public osgDB::ReaderWriter
|
||||
{
|
||||
flags |= FT_LOAD_MONOCHROME;
|
||||
}
|
||||
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const
|
||||
{
|
||||
std::string ext = osgDB::getLowerCaseFileExtension(file);
|
||||
std::string tmpFile = file;
|
||||
bool needFont3D = false;
|
||||
|
||||
std::string ext = osgDB::getLowerCaseFileExtension(tmpFile);
|
||||
if (ext == "text3d")
|
||||
{
|
||||
needFont3D = true;
|
||||
tmpFile.erase(tmpFile.size()-7, 7);
|
||||
ext = osgDB::getLowerCaseFileExtension(tmpFile);
|
||||
}
|
||||
else if ((options != NULL) && (options->getPluginData("3D")))
|
||||
{
|
||||
needFont3D = true;
|
||||
}
|
||||
|
||||
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
std::string fileName = osgDB::findDataFile( file, options );
|
||||
std::string fileName = osgDB::findDataFile( tmpFile, options );
|
||||
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
|
||||
FreeTypeLibrary* freeTypeLibrary = FreeTypeLibrary::instance();
|
||||
if (!freeTypeLibrary)
|
||||
if (!freeTypeLibrary)
|
||||
{
|
||||
osg::notify(osg::WARN)<<"Warning:: cannot create freetype font after freetype library has been deleted."<<std::endl;
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
}
|
||||
|
||||
if ( (options != NULL) && (options->getPluginData("3D")) )
|
||||
if (needFont3D)
|
||||
return freeTypeLibrary->getFont3D(fileName,0,getFlags(options));
|
||||
else
|
||||
return freeTypeLibrary->getFont(fileName,0,getFlags(options));
|
||||
@ -60,7 +75,7 @@ class ReaderWriterFreeType : public osgDB::ReaderWriter
|
||||
virtual ReadResult readObject(std::istream& stream, const osgDB::ReaderWriter::Options* options) const
|
||||
{
|
||||
FreeTypeLibrary* freeTypeLibrary = FreeTypeLibrary::instance();
|
||||
if (!freeTypeLibrary)
|
||||
if (!freeTypeLibrary)
|
||||
{
|
||||
osg::notify(osg::WARN)<<"Warning:: cannot create freetype font after freetype library has been deleted."<<std::endl;
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
|
@ -1,13 +1,13 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
@ -86,7 +86,7 @@ std::string findFont3DFile(const std::string& str)
|
||||
}
|
||||
|
||||
// Not found, return empty string
|
||||
osg::notify(osg::WARN)<<"Warning: font file \""<<str<<"\" not found."<<std::endl;
|
||||
osg::notify(osg::WARN)<<"Warning: font file \""<<str<<"\" not found."<<std::endl;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
@ -94,9 +94,22 @@ osgText::Font3D* readFont3DFile(const std::string& filename, const osgDB::Reader
|
||||
{
|
||||
if (filename=="") return 0;
|
||||
|
||||
std::string foundFile = findFont3DFile(filename);
|
||||
// unsure filename have not .text3d at the end
|
||||
std::string tmpFilename;
|
||||
std::string text3dExt = ".text3d";
|
||||
std::string ext = osgDB::getFileExtensionIncludingDot(filename);
|
||||
if (ext == text3dExt)
|
||||
tmpFilename = filename.substr(filename.size() - ext.size(), ext.size());
|
||||
else
|
||||
tmpFilename = filename;
|
||||
|
||||
//search font file
|
||||
std::string foundFile = findFont3DFile(tmpFilename);
|
||||
if (foundFile.empty()) return 0;
|
||||
|
||||
|
||||
//unsure filename have .text3d at the end
|
||||
foundFile += text3dExt;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_Font3DFileMutex);
|
||||
|
||||
osg::ref_ptr<osgDB::ReaderWriter::Options> localOptions;
|
||||
@ -104,16 +117,10 @@ osgText::Font3D* readFont3DFile(const std::string& filename, const osgDB::Reader
|
||||
{
|
||||
localOptions = new osgDB::ReaderWriter::Options;
|
||||
localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS);
|
||||
// ** HACK to load Font3D instead of Font
|
||||
localOptions->setPluginData("3D", (void*) 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
userOptions->setPluginData("3D", (void*) 1);
|
||||
}
|
||||
|
||||
osg::Object* object = osgDB::readObjectFile(foundFile, userOptions ? userOptions : localOptions.get());
|
||||
|
||||
|
||||
// if the object is a font then return it.
|
||||
osgText::Font3D* font3D = dynamic_cast<osgText::Font3D*>(object);
|
||||
if (font3D) return font3D;
|
||||
@ -142,7 +149,7 @@ osgText::Font3D* readFont3DStream(std::istream& stream, const osgDB::ReaderWrite
|
||||
// there should be a better way to get the FreeType ReaderWriter by name...
|
||||
osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension("ttf");
|
||||
if (reader == 0) return 0;
|
||||
|
||||
|
||||
osgDB::ReaderWriter::ReadResult rr = reader->readObject(stream, userOptions ? userOptions : localOptions.get());
|
||||
if (rr.error())
|
||||
{
|
||||
@ -150,7 +157,7 @@ osgText::Font3D* readFont3DStream(std::istream& stream, const osgDB::ReaderWrite
|
||||
return 0;
|
||||
}
|
||||
if (!rr.validObject()) return 0;
|
||||
|
||||
|
||||
osg::Object *object = rr.takeObject();
|
||||
|
||||
// if the object is a font then return it.
|
||||
@ -166,9 +173,19 @@ osg::ref_ptr<Font3D> readRefFont3DFile(const std::string& filename, const osgDB:
|
||||
{
|
||||
if (filename=="") return 0;
|
||||
|
||||
std::string foundFile = findFont3DFile(filename);
|
||||
std::string tmpFilename;
|
||||
std::string text3dExt = ".text3d";
|
||||
std::string ext = osgDB::getFileExtensionIncludingDot(filename);
|
||||
if (ext == text3dExt)
|
||||
tmpFilename = filename.substr(0, filename.size() - ext.size());
|
||||
else
|
||||
tmpFilename = filename;
|
||||
|
||||
std::string foundFile = findFont3DFile(tmpFilename);
|
||||
if (foundFile.empty()) return 0;
|
||||
|
||||
|
||||
foundFile += text3dExt;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_Font3DFileMutex);
|
||||
|
||||
osg::ref_ptr<osgDB::ReaderWriter::Options> localOptions;
|
||||
@ -176,16 +193,10 @@ osg::ref_ptr<Font3D> readRefFont3DFile(const std::string& filename, const osgDB:
|
||||
{
|
||||
localOptions = new osgDB::ReaderWriter::Options;
|
||||
localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS);
|
||||
// ** HACK to load Font3D instead of Font
|
||||
localOptions->setPluginData("3D", (void*) 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
userOptions->setPluginData("3D", (void*) 1);
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Object> object = osgDB::readRefObjectFile(foundFile, userOptions ? userOptions : localOptions.get());
|
||||
|
||||
|
||||
// if the object is a font then return it.
|
||||
osgText::Font3D* font3D = dynamic_cast<osgText::Font3D*>(object.get());
|
||||
if (font3D) return osg::ref_ptr<Font3D>(font3D);
|
||||
@ -212,7 +223,7 @@ osg::ref_ptr<Font3D> readRefFont3DStream(std::istream& stream, const osgDB::Read
|
||||
// there should be a better way to get the FreeType ReaderWriter by name...
|
||||
osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension("ttf");
|
||||
if (reader == 0) return 0;
|
||||
|
||||
|
||||
osgDB::ReaderWriter::ReadResult rr = reader->readObject(stream, userOptions ? userOptions : localOptions.get());
|
||||
if (rr.error())
|
||||
{
|
||||
@ -267,24 +278,24 @@ std::string Font3D::getFileName() const
|
||||
|
||||
Font3D::Glyph3D* Font3D::getGlyph(unsigned int charcode)
|
||||
{
|
||||
Glyph3D * glyph3D = NULL;
|
||||
|
||||
Glyph3D * glyph3D = NULL;
|
||||
|
||||
Glyph3DMap::iterator itr = _glyph3DMap.find(charcode);
|
||||
if (itr!=_glyph3DMap.end()) glyph3D = itr->second.get();
|
||||
|
||||
|
||||
else if (_implementation.valid())
|
||||
{
|
||||
glyph3D = _implementation->getGlyph(charcode);
|
||||
if (glyph3D) _glyph3DMap[charcode] = glyph3D;
|
||||
}
|
||||
|
||||
|
||||
return glyph3D;
|
||||
}
|
||||
|
||||
void Font3D::setThreadSafeRefUnref(bool threadSafe)
|
||||
{
|
||||
Glyph3DMap::iterator it,end = _glyph3DMap.end();
|
||||
|
||||
|
||||
for (it=_glyph3DMap.begin(); it!=end; ++it)
|
||||
it->second->setThreadSafeRefUnref(threadSafe);
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <osgText/Text3D>
|
||||
#include <osg/io_utils>
|
||||
namespace osgText
|
||||
namespace osgText
|
||||
{
|
||||
|
||||
Text3D::Text3D():
|
||||
@ -32,25 +32,66 @@ Text3D::Text3D(const Text3D & text3D, const osg::CopyOp & copyop):
|
||||
computeGlyphRepresentation();
|
||||
}
|
||||
|
||||
//void Text3D::accept(osg::Drawable::ConstAttributeFunctor& af) const
|
||||
//{
|
||||
// TODO
|
||||
//}
|
||||
void Text3D::accept(osg::Drawable::ConstAttributeFunctor& af) const
|
||||
{
|
||||
// ** for each line, do ...
|
||||
TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
|
||||
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
|
||||
{
|
||||
// ** for each glyph in the line, do ...
|
||||
LineRenderInfo::const_iterator it, end = itLine->end();
|
||||
for (it = itLine->begin(); it!=end; ++it)
|
||||
{
|
||||
// ** apply the vertex array
|
||||
af.apply(osg::Drawable::VERTICES, it->_glyph->getVertexArray()->size(), &(it->_glyph->getVertexArray()->front()));
|
||||
}
|
||||
}
|
||||
}
|
||||
void Text3D::accept(osg::PrimitiveFunctor& pf) const
|
||||
{
|
||||
// ** for each line, do ...
|
||||
TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
|
||||
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
|
||||
{
|
||||
// ** for each glyph in the line, do ...
|
||||
LineRenderInfo::const_iterator it, end = itLine->end();
|
||||
for (it = itLine->begin(); it!=end; ++it)
|
||||
{
|
||||
pf.setVertexArray(it->_glyph->getVertexArray()->size(),&(it->_glyph->getVertexArray()->front()));
|
||||
|
||||
//void Text3D::accept(osg::PrimitiveFunctor& /*pf*/) const
|
||||
//{
|
||||
// TODO
|
||||
//}
|
||||
// ** render the front face of the glyph
|
||||
osg::Geometry::PrimitiveSetList & pslFront = it->_glyph->getFrontPrimitiveSetList();
|
||||
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr)
|
||||
{
|
||||
(*itr)->accept(pf);
|
||||
}
|
||||
|
||||
// ** render the wall face of the glyph
|
||||
osg::Geometry::PrimitiveSetList & pslWall = it->_glyph->getWallPrimitiveSetList();
|
||||
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslWall.begin(), end=pslWall.end(); itr!=end; ++itr)
|
||||
{
|
||||
(*itr)->accept(pf);
|
||||
}
|
||||
|
||||
// ** render the back face of the glyph
|
||||
osg::Geometry::PrimitiveSetList & pslBack = it->_glyph->getBackPrimitiveSetList();
|
||||
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr)
|
||||
{
|
||||
(*itr)->accept(pf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Text3D::setFont(osg::ref_ptr<Font3D> font)
|
||||
{
|
||||
{
|
||||
_font = font;
|
||||
|
||||
|
||||
computeGlyphRepresentation();
|
||||
}
|
||||
|
||||
void Text3D::setFont(const std::string & fontfile)
|
||||
{
|
||||
{
|
||||
setFont(readRefFont3DFile(fontfile));
|
||||
}
|
||||
|
||||
@ -75,11 +116,11 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i
|
||||
|
||||
float maximumHeight = _maximumHeight / _font->getScale();
|
||||
float maximumWidth = _maximumWidth / _font->getScale();
|
||||
|
||||
|
||||
for(bool outOfSpace=false;lastChar!=last;++lastChar)
|
||||
{
|
||||
unsigned int charcode = *lastChar;
|
||||
|
||||
|
||||
if (charcode=='\n')
|
||||
{
|
||||
return lastChar;
|
||||
@ -89,16 +130,16 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i
|
||||
if (glyph)
|
||||
{
|
||||
const osg::BoundingBox & bb = glyph->getBoundingBox();
|
||||
|
||||
|
||||
// adjust cursor position w.r.t any kerning.
|
||||
if (previous_charcode)
|
||||
{
|
||||
|
||||
|
||||
if (_layout == RIGHT_TO_LEFT)
|
||||
{
|
||||
cursor.x() -= glyph->getHorizontalAdvance();
|
||||
}
|
||||
|
||||
|
||||
if (kerning)
|
||||
{
|
||||
switch (_layout)
|
||||
@ -119,7 +160,7 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
switch (_layout)
|
||||
{
|
||||
case LEFT_TO_RIGHT:
|
||||
@ -135,10 +176,10 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i
|
||||
case VERTICAL:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
switch(_layout)
|
||||
{
|
||||
@ -158,7 +199,7 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i
|
||||
if (maximumHeight>0.0f && cursor.y()<-maximumHeight) outOfSpace=true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// => word boundary detection & wrapping
|
||||
if (outOfSpace) break;
|
||||
|
||||
@ -175,17 +216,17 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// word boundary detection & wrapping
|
||||
if (lastChar!=last)
|
||||
{
|
||||
if (deliminatorSet.count(*lastChar)==0)
|
||||
if (deliminatorSet.count(*lastChar)==0)
|
||||
{
|
||||
String::iterator lastValidChar = lastChar;
|
||||
while (lastValidChar!=first && deliminatorSet.count(*lastValidChar)==0)
|
||||
{
|
||||
--lastValidChar;
|
||||
|
||||
|
||||
//Substract off glyphs from the cursor position (to correctly center text)
|
||||
Font3D::Glyph3D* glyph = _font->getGlyph(*lastValidChar);
|
||||
if (glyph)
|
||||
@ -198,7 +239,7 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (first!=lastValidChar)
|
||||
{
|
||||
++lastValidChar;
|
||||
@ -213,17 +254,17 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i
|
||||
void Text3D::computeGlyphRepresentation()
|
||||
{
|
||||
if (_font.valid() == false) return;
|
||||
|
||||
|
||||
_textRenderInfo.clear();
|
||||
_lineCount = 0;
|
||||
|
||||
if (_text.empty())
|
||||
|
||||
if (_text.empty())
|
||||
{
|
||||
_textBB.set(0,0,0, 0,0,0);//no size text
|
||||
TextBase::computePositions(); //to reset the origin
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// initialize bounding box, it will be expanded during glyph position calculation
|
||||
_textBB.init();
|
||||
|
||||
@ -231,31 +272,31 @@ void Text3D::computeGlyphRepresentation()
|
||||
osg::Vec2 cursor(startOfLine_coords);
|
||||
osg::Vec2 local(0.0f,0.0f);
|
||||
osg::Vec2 startOffset(0.0f,0.0f);
|
||||
|
||||
|
||||
unsigned int previous_charcode = 0;
|
||||
unsigned int linelength = 0;
|
||||
bool kerning = true;
|
||||
|
||||
|
||||
unsigned int lineNumber = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
for(String::iterator itr=_text.begin(); itr!=_text.end(); )
|
||||
{
|
||||
_textRenderInfo.resize(lineNumber + 1);
|
||||
LineRenderInfo & currentLineRenderInfo = _textRenderInfo.back();
|
||||
|
||||
|
||||
// record the start of the current line
|
||||
String::iterator startOfLine_itr = itr;
|
||||
|
||||
// find the end of the current line.
|
||||
osg::Vec2 endOfLine_coords(cursor);
|
||||
String::iterator endOfLine_itr = computeLastCharacterOnLine(endOfLine_coords, itr,_text.end());
|
||||
|
||||
// ** position the cursor function to the Layout and the alignement
|
||||
|
||||
// ** position the cursor function to the Layout and the alignement
|
||||
TextBase::positionCursor(endOfLine_coords, cursor, (unsigned int) (endOfLine_itr - startOfLine_itr));
|
||||
|
||||
|
||||
|
||||
if (itr!=endOfLine_itr)
|
||||
{
|
||||
for(;itr!=endOfLine_itr;++itr)
|
||||
@ -266,7 +307,7 @@ void Text3D::computeGlyphRepresentation()
|
||||
if (glyph)
|
||||
{
|
||||
const osg::BoundingBox & bb = glyph->getBoundingBox();
|
||||
|
||||
|
||||
// adjust cursor position w.r.t any kerning.
|
||||
if (previous_charcode)
|
||||
{
|
||||
@ -274,7 +315,7 @@ void Text3D::computeGlyphRepresentation()
|
||||
{
|
||||
cursor.x() -= glyph->getHorizontalAdvance();
|
||||
}
|
||||
|
||||
|
||||
if (kerning)
|
||||
{
|
||||
switch (_layout)
|
||||
@ -295,7 +336,7 @@ void Text3D::computeGlyphRepresentation()
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
switch (_layout)
|
||||
{
|
||||
case LEFT_TO_RIGHT:
|
||||
@ -314,19 +355,19 @@ void Text3D::computeGlyphRepresentation()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
local = cursor;
|
||||
|
||||
|
||||
if (_layout==VERTICAL)
|
||||
{
|
||||
local.x() += -glyph->getVerticalBearing().x();
|
||||
local.y() += -glyph->getVerticalBearing().y();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// move the cursor onto the next character.
|
||||
// also expand bounding box
|
||||
switch (_layout)
|
||||
@ -344,14 +385,14 @@ void Text3D::computeGlyphRepresentation()
|
||||
case RIGHT_TO_LEFT:
|
||||
_textBB.expandBy(osg::Vec3(cursor.x()+bb.xMax(), cursor.y() + bb.yMax(), 0.0f)); //upper right corner
|
||||
_textBB.expandBy(osg::Vec3(cursor.x()+bb.xMin(), cursor.y()+bb.yMin(), 0.0f)); //lower left corner
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
osg::Vec3 pos = osg::Vec3(local.x(), local.y(), 0.0f);
|
||||
currentLineRenderInfo.push_back(Text3D::GlyphRenderInfo(glyph, pos));
|
||||
|
||||
|
||||
|
||||
previous_charcode = charcode;
|
||||
}
|
||||
}
|
||||
@ -360,13 +401,13 @@ void Text3D::computeGlyphRepresentation()
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
|
||||
|
||||
if (itr!=_text.end())
|
||||
{
|
||||
// skip over return.
|
||||
if (*itr=='\n') ++itr;
|
||||
}
|
||||
|
||||
|
||||
// move to new line.
|
||||
switch(_layout)
|
||||
{
|
||||
@ -394,12 +435,10 @@ void Text3D::computeGlyphRepresentation()
|
||||
++lineNumber;
|
||||
}
|
||||
_textBB.expandBy(0.0f,0.0f,-1);
|
||||
|
||||
|
||||
TextBase::computePositions();
|
||||
}
|
||||
|
||||
|
||||
|
||||
osg::BoundingBox Text3D::computeBound() const
|
||||
{
|
||||
osg::BoundingBox bbox;
|
||||
@ -410,25 +449,17 @@ osg::BoundingBox Text3D::computeBound() const
|
||||
{
|
||||
osg::Matrix& matrix = _autoTransformCache[i]._matrix;
|
||||
bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*matrix);
|
||||
// bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*matrix);
|
||||
bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMax())*matrix);
|
||||
// bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*matrix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return bbox;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void Text3D::computePositions(unsigned int contextID) const
|
||||
{
|
||||
if (_font.valid() == false) return;
|
||||
|
||||
|
||||
switch(_alignment)
|
||||
{
|
||||
case LEFT_TOP: _offset.set(_textBB.xMin(),_textBB.yMax(),_textBB.zMin()); break;
|
||||
@ -446,16 +477,16 @@ void Text3D::computePositions(unsigned int contextID) const
|
||||
case LEFT_BASE_LINE: _offset.set(0.0f,0.0f,0.0f); break;
|
||||
case CENTER_BASE_LINE: _offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,0.0f,0.0f); break;
|
||||
case RIGHT_BASE_LINE: _offset.set(_textBB.xMax(),0.0f,0.0f); break;
|
||||
|
||||
|
||||
case LEFT_BOTTOM_BASE_LINE: _offset.set(0.0f,-_characterHeight*(_lineCount-1),0.0f); break;
|
||||
case CENTER_BOTTOM_BASE_LINE: _offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,-_characterHeight*(_lineCount-1),0.0f); break;
|
||||
case RIGHT_BOTTOM_BASE_LINE: _offset.set(_textBB.xMax(),-_characterHeight*(_lineCount-1),0.0f); break;
|
||||
}
|
||||
|
||||
|
||||
AutoTransformCache& atc = _autoTransformCache[contextID];
|
||||
osg::Matrix& matrix = atc._matrix;
|
||||
|
||||
|
||||
|
||||
float scale = _font->getScale();
|
||||
osg::Vec3 scaleVec(scale * _characterHeight, scale * _characterHeight / _characterAspectRatio, _characterDepth);
|
||||
matrix.makeTranslate(-_offset);
|
||||
@ -463,19 +494,19 @@ void Text3D::computePositions(unsigned int contextID) const
|
||||
matrix.postMultRotate(_rotation);
|
||||
matrix.postMultTranslate(_position);
|
||||
|
||||
|
||||
|
||||
_normal = osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),matrix);
|
||||
_normal.normalize();
|
||||
|
||||
const_cast<Text3D*>(this)->dirtyBound();
|
||||
const_cast<Text3D*>(this)->dirtyBound();
|
||||
}
|
||||
|
||||
void Text3D::drawImplementation(osg::RenderInfo& renderInfo) const
|
||||
{
|
||||
osg::State & state = *renderInfo.getState();
|
||||
unsigned int contextID = state.getContextID();
|
||||
|
||||
|
||||
|
||||
|
||||
// ** save the previous modelview matrix
|
||||
osg::ref_ptr<osg::RefMatrix> previous(new osg::RefMatrix(state.getModelViewMatrix()));
|
||||
|
||||
@ -484,25 +515,25 @@ void Text3D::drawImplementation(osg::RenderInfo& renderInfo) const
|
||||
|
||||
// ** mult previous by the modelview for this context
|
||||
modelview->postMult(*previous.get());
|
||||
|
||||
|
||||
// ** apply this new modelview matrix
|
||||
state.applyModelViewMatrix(modelview.get());
|
||||
|
||||
|
||||
|
||||
|
||||
if (_drawMode & TEXT)
|
||||
{
|
||||
renderInfo.getState()->disableAllVertexArrays();
|
||||
|
||||
|
||||
glPushAttrib(GL_TRANSFORM_BIT);
|
||||
glEnable(GL_RESCALE_NORMAL);
|
||||
|
||||
|
||||
switch(_renderMode)
|
||||
{
|
||||
case PER_FACE: renderPerFace(*renderInfo.getState()); break;
|
||||
case PER_GLYPH:
|
||||
default: renderPerGlyph(*renderInfo.getState()); break;
|
||||
}
|
||||
|
||||
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
@ -514,41 +545,41 @@ void Text3D::drawImplementation(osg::RenderInfo& renderInfo) const
|
||||
osg::Vec3 c100(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMax()));
|
||||
osg::Vec3 c110(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMax()));
|
||||
osg::Vec3 c010(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMax()));
|
||||
|
||||
|
||||
osg::Vec3 c001(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin()));
|
||||
osg::Vec3 c101(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin()));
|
||||
osg::Vec3 c111(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin()));
|
||||
osg::Vec3 c011(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin()));
|
||||
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3fv(c000.ptr());
|
||||
glVertex3fv(c100.ptr());
|
||||
glVertex3fv(c110.ptr());
|
||||
glVertex3fv(c010.ptr());
|
||||
glEnd();
|
||||
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3fv(c001.ptr());
|
||||
glVertex3fv(c011.ptr());
|
||||
glVertex3fv(c111.ptr());
|
||||
glVertex3fv(c101.ptr());
|
||||
glEnd();
|
||||
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex3fv(c000.ptr());
|
||||
glVertex3fv(c001.ptr());
|
||||
|
||||
|
||||
glVertex3fv(c100.ptr());
|
||||
glVertex3fv(c101.ptr());
|
||||
|
||||
|
||||
glVertex3fv(c110.ptr());
|
||||
glVertex3fv(c111.ptr());
|
||||
|
||||
|
||||
glVertex3fv(c010.ptr());
|
||||
glVertex3fv(c011.ptr());
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_drawMode & ALIGNMENT)
|
||||
{
|
||||
@ -565,17 +596,15 @@ void Text3D::drawImplementation(osg::RenderInfo& renderInfo) const
|
||||
glVertex3fv(vt.ptr());
|
||||
glVertex3fv(vb.ptr());
|
||||
glEnd();
|
||||
|
||||
|
||||
}
|
||||
|
||||
// restore the previous modelview matrix
|
||||
state.applyModelViewMatrix(previous.get());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Text3D::renderPerGlyph(osg::State & state) const
|
||||
{
|
||||
{
|
||||
// ** for each line, do ...
|
||||
TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
|
||||
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
|
||||
@ -584,24 +613,23 @@ void Text3D::renderPerGlyph(osg::State & state) const
|
||||
LineRenderInfo::const_iterator it, end = itLine->end();
|
||||
for (it = itLine->begin(); it!=end; ++it)
|
||||
{
|
||||
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glTranslatef(it->_position.x(), it->_position.y(), it->_position.z());
|
||||
|
||||
|
||||
// ** apply the vertex array
|
||||
state.setVertexPointer(it->_glyph->getVertexArray());
|
||||
|
||||
|
||||
// ** render the front face of the glyph
|
||||
glNormal3f(0.0f,0.0f,1.0f);
|
||||
|
||||
|
||||
osg::Geometry::PrimitiveSetList & pslFront = it->_glyph->getFrontPrimitiveSetList();
|
||||
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr)
|
||||
{
|
||||
|
||||
(*itr)->draw(state, false);
|
||||
}
|
||||
|
||||
|
||||
// ** render the wall face of the glyph
|
||||
state.setNormalPointer(it->_glyph->getNormalArray());
|
||||
osg::Geometry::PrimitiveSetList & pslWall = it->_glyph->getWallPrimitiveSetList();
|
||||
@ -609,16 +637,17 @@ void Text3D::renderPerGlyph(osg::State & state) const
|
||||
{
|
||||
(*itr)->draw(state, false);
|
||||
}
|
||||
|
||||
state.disableNormalPointer();
|
||||
|
||||
// ** render the back face of the glyph
|
||||
glNormal3f(0.0f,0.0f,-1.0f);
|
||||
|
||||
|
||||
osg::Geometry::PrimitiveSetList & pslBack = it->_glyph->getBackPrimitiveSetList();
|
||||
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr)
|
||||
{
|
||||
(*itr)->draw(state, false);
|
||||
}
|
||||
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
@ -628,18 +657,18 @@ void Text3D::renderPerFace(osg::State & state) const
|
||||
{
|
||||
// ** render all front faces
|
||||
glNormal3f(0.0f,0.0f,1.0f);
|
||||
|
||||
|
||||
TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
|
||||
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
|
||||
{
|
||||
// ** for each glyph in the line, do ...
|
||||
LineRenderInfo::const_iterator it, end = itLine->end();
|
||||
for (it = itLine->begin(); it!=end; ++it)
|
||||
for (it = itLine->begin(); it!=end; ++it)
|
||||
{
|
||||
glPushMatrix();
|
||||
glTranslatef(it->_position.x(), it->_position.y(), it->_position.z());
|
||||
state.setVertexPointer(it->_glyph->getVertexArray());
|
||||
|
||||
|
||||
// ** render the front face of the glyph
|
||||
osg::Geometry::PrimitiveSetList & psl = it->_glyph->getFrontPrimitiveSetList();
|
||||
for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr)
|
||||
@ -649,7 +678,7 @@ void Text3D::renderPerFace(osg::State & state) const
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ** render all wall face of the text
|
||||
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
|
||||
@ -662,7 +691,7 @@ void Text3D::renderPerFace(osg::State & state) const
|
||||
glTranslatef(it->_position.x(), it->_position.y(), it->_position.z());
|
||||
state.setVertexPointer(it->_glyph->getVertexArray());
|
||||
state.setNormalPointer(it->_glyph->getNormalArray());
|
||||
|
||||
|
||||
osg::Geometry::PrimitiveSetList & psl = it->_glyph->getWallPrimitiveSetList();
|
||||
for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr)
|
||||
{
|
||||
@ -672,10 +701,10 @@ void Text3D::renderPerFace(osg::State & state) const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ** render all back face of the text
|
||||
glNormal3f(0.0f,0.0f,-1.0f);
|
||||
|
||||
|
||||
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
|
||||
{
|
||||
// ** for each glyph in the line, do ...
|
||||
@ -685,7 +714,7 @@ void Text3D::renderPerFace(osg::State & state) const
|
||||
glPushMatrix();
|
||||
glTranslatef(it->_position.x(), it->_position.y(), it->_position.z());
|
||||
state.setVertexPointer(it->_glyph->getVertexArray());
|
||||
|
||||
|
||||
// ** render the back face of the glyph
|
||||
osg::Geometry::PrimitiveSetList & psl = it->_glyph->getBackPrimitiveSetList();
|
||||
for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr)
|
||||
@ -709,14 +738,14 @@ void Text3D::setThreadSafeRefUnref(bool threadSafe)
|
||||
void Text3D::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
{
|
||||
TextBase::resizeGLObjectBuffers(maxSize);
|
||||
|
||||
|
||||
if (_font.valid()) _font->resizeGLObjectBuffers(maxSize);
|
||||
}
|
||||
|
||||
void Text3D::releaseGLObjects(osg::State* state) const
|
||||
{
|
||||
TextBase::releaseGLObjects(state);
|
||||
|
||||
|
||||
if (_font.valid()) _font->releaseGLObjects(state);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user