Changeset 9881

Show
Ignore:
Timestamp:
03/10/09 11:56:00 (4 years ago)
Author:
robert
Message:

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.
"

Location:
OpenSceneGraph/trunk
Files:
7 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/include/osgText/Font3D

    r7874 r9881  
    1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield  
     1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
    22 * 
    3  * This library is open source and may be redistributed and/or modified under   
    4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or  
     3 * This library is open source and may be redistributed and/or modified under 
     4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
    55 * (at your option) any later version.  The full license is in LICENSE file 
    66 * included with this distribution, and on the openscenegraph.org website. 
    7  *  
     7 * 
    88 * This library is distributed in the hope that it will be useful, 
    99 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
     10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1111 * OpenSceneGraph Public License for more details. 
    1212*/ 
     
    3232 
    3333/** Read a font from specified file. The filename may contain a path. 
    34   * It will search for the font file in the following places in this order:  
     34  * It will search for the font file in the following places in this order: 
    3535  * - In the current directory 
    3636  * - All paths defined in OSG_FILE_PATH or OSGFILEPATH environment variable 
     
    4646  * - Other OS: In /usr/share/fonts/ttf/western 
    4747  * - Other OS: In /usr/share/fonts/ttf/decoratives 
    48   *  
     48  * 
    4949  * If the given file could not be found, the path part will be stripped and 
    5050  * the file will be searched again in the OS specific directories. 
     
    6868// declare the interface to a font. 
    6969public: 
    70      
     70 
    7171    // forward declare nested classes. 
    7272    class Glyph3D; 
     
    9393    /** Get a Glyph for specified charcode, and the font size nearest to the current font size hint.*/ 
    9494    virtual Glyph3D* getGlyph(unsigned int charcode); 
    95      
     95 
    9696    /** Return true if this font provides vertical alignments and spacing or glyphs.*/ 
    9797    virtual bool hasVertical() const; 
     
    9999    /** Return the scale to apply on the glyph to have a charactere size equal to 1 */ 
    100100    virtual float getScale() const { return _implementation->getScale(); }; 
    101      
     101 
    102102    // make Text a friend to allow it add and remove its entry in the Font's _textList. 
    103103    friend class Font3DImplementation; 
     
    110110    /** Set whether to use a mutex to ensure ref() and unref() */ 
    111111    virtual void setThreadSafeRefUnref(bool threadSafe); 
    112      
     112 
    113113    typedef OpenThreads::Mutex Font3DMutex; 
    114114 
     
    116116 
    117117    virtual ~Font3D(); 
    118      
     118 
    119119//    void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph* glyph); 
    120120    void addGlyph(unsigned int charcode, Glyph3D* glyph); 
    121      
     121 
    122122    // current active size of font 
    123123    unsigned int                        _depth; 
     
    128128 
    129129    typedef std::map<char, osg::ref_ptr<Glyph3D> > Glyph3DMap; 
    130     Glyph3DMap _glyph3DMap;  
    131      
     130    Glyph3DMap _glyph3DMap; 
     131 
    132132    osg::ref_ptr<Font3DImplementation> _implementation; 
    133133 
    134      
     134 
    135135// declare the nested classes. 
    136136public: 
     
    139139    { 
    140140    public: 
    141      
     141 
    142142        Font3DImplementation(): 
    143143            osg::Referenced(true), 
    144144            _facade(0) {} 
    145      
     145 
    146146        virtual std::string getFileName() const = 0; 
    147147 
     
    154154        /** Return true if this font provides vertical alignments and spacing or glyphs.*/ 
    155155        virtual bool hasVertical() const = 0; 
    156          
     156 
    157157        virtual float getScale() const = 0; 
    158    
     158 
    159159        void setFontWidth(unsigned int width) { _facade->_width = width; } 
    160160 
    161161        void setFontHeight(unsigned int height) { _facade->_height = height; } 
    162          
     162 
    163163        void setFontDepth(unsigned int depth) { _facade->_depth = depth; } 
    164          
     164 
    165165//        void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph3D* glyph) 
    166166//        { 
    167167//            _facade->addGlyph(width, height, charcode, glyph); 
    168168//        } 
    169 //         
     169// 
    170170//        void addGlyph(unsigned int charcode, Glyph3D* glyph) 
    171171//        { 
     
    182182        Glyph3D(unsigned int glyphCode): 
    183183            osg::Referenced(true), 
    184             _glyphCode(glyphCode),  
     184            _glyphCode(glyphCode), 
    185185            _horizontalBearing(0,0), 
    186186            _horizontalAdvance(0), 
     
    188188            _verticalAdvance(0) 
    189189            {} 
    190          
     190 
    191191 
    192192        /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ 
    193193//        virtual int compare(const osg::StateAttribute& rhs) const; 
    194 //         
     194// 
    195195//        virtual void apply(osg::State& state) const; 
    196196 
    197          
    198          
     197 
     198 
    199199        unsigned int getGlyphCode() const { return _glyphCode; } 
    200          
     200 
    201201        void setHorizontalBearing(const osg::Vec2& bearing) { _horizontalBearing=bearing; } 
    202202        const osg::Vec2 & getHorizontalBearing() const { return _horizontalBearing; } 
    203          
     203 
    204204        void setHorizontalAdvance(float advance) { _horizontalAdvance=advance; } 
    205205        float getHorizontalAdvance() const { return _horizontalAdvance; } 
     
    210210        void setVerticalAdvance(float advance) { _verticalAdvance=advance; } 
    211211        float getVerticalAdvance() const { return _verticalAdvance; } 
    212                  
     212 
    213213        void setBoundingBox(osg::BoundingBox & bb) { _bb=bb; } 
    214214        const osg::BoundingBox & getBoundingBox() const { return _bb; } 
    215          
    216          
     215 
     216 
    217217        /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ 
    218218        virtual void setThreadSafeRefUnref(bool threadSafe); 
    219219 
    220          
     220 
    221221        /** Get the PrimitiveSetList for the front face. */ 
    222222        osg::Geometry::PrimitiveSetList & getFrontPrimitiveSetList() { return _frontPrimitiveSetList; } 
     
    225225        /** Get et the PrimitiveSetList for the back face. */ 
    226226        osg::Geometry::PrimitiveSetList & getBackPrimitiveSetList() { return _backPrimitiveSetList; } 
    227          
     227 
    228228        /** Set the VertexArray of the glyph. */ 
    229229        void setVertexArray(osg::Vec3Array * va) { _vertexArray = va; } 
    230230        /** Get the VertexArray of the glyph. */ 
    231231        osg::Vec3Array * getVertexArray() { return _vertexArray.get(); } 
     232        /** Set the VertexArray of the glyph. */ 
     233        void setNormalArray(osg::Vec3Array * na) { _normalArray = na; } 
    232234        /** Get the NormalArray for the wall face. */ 
    233235        osg::Vec3Array * getNormalArray() { return _normalArray.get(); } 
    234          
     236 
    235237        float getHorizontalWidth() { return (-_horizontalBearing.x() + _horizontalAdvance); } 
    236238        float getHorizontalHeight() { return (-_horizontalBearing.y() + _bb.yMax()); } 
    237239        float getVerticalWidth() { return (-_verticalBearing.x() + _bb.xMax()); } 
    238240        float getVerticalHeight() { return (-_verticalBearing.y() + _verticalAdvance); } 
    239          
     241 
    240242        void setWidth(float width) { _width = width; } 
    241243        float getWidth() { return _width; } 
    242          
     244 
    243245        void setHeight(float height) { _height = height; } 
    244246        float getHeight() { return _height; } 
    245          
     247 
    246248    protected: 
    247      
     249 
    248250        virtual ~Glyph3D() {} 
    249251 
     
    256258        float                       _verticalAdvance; 
    257259 
    258         osg::BoundingBox            _bb;         
     260        osg::BoundingBox            _bb; 
    259261//        osg::Vec2                   _advance; 
    260          
     262 
    261263        float _width; 
    262264        float _height; 
    263          
    264          
     265 
     266 
    265267        osg::ref_ptr<osg::Vec3Array> _vertexArray; 
    266268        osg::ref_ptr<osg::Vec3Array> _normalArray; 
    267          
     269 
    268270        osg::Geometry::PrimitiveSetList _frontPrimitiveSetList; 
    269271        osg::Geometry::PrimitiveSetList _wallPrimitiveSetList; 
    270272        osg::Geometry::PrimitiveSetList _backPrimitiveSetList; 
    271          
    272          
     273 
     274 
    273275    }; 
    274276 
  • OpenSceneGraph/trunk/include/osgText/Text3D

    r8441 r9881  
    1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield  
     1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
    22 * 
    3  * This library is open source and may be redistributed and/or modified under   
    4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or  
     3 * This library is open source and may be redistributed and/or modified under 
     4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
    55 * (at your option) any later version.  The full license is in LICENSE file 
    66 * included with this distribution, and on the openscenegraph.org website. 
    7  *  
     7 * 
    88 * This library is distributed in the hope that it will be useful, 
    99 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
     10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1111 * OpenSceneGraph Public License for more details. 
    1212*/ 
     
    3131     *                   all wall face with the wall StateSet 
    3232     *                   all back face with the back StateSet (back face of the character, no the OpenGL back face) 
    33      *  
     33     * 
    3434     * PER_GLYPH : render all Charactere with the default StateSet 
    3535     */ 
     
    3939        PER_GLYPH 
    4040    }; 
    41      
     41 
    4242    Text3D(); 
    4343    Text3D(const Text3D& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); 
     
    4949    /** Set the Charactere Depth of text. */ 
    5050    void setCharacterDepth(float characterDepth) { _characterDepth = characterDepth; computeGlyphRepresentation(); } 
    51      
     51 
    5252    /** Get the render mode used to render the text. */ 
    5353    RenderMode getRenderMode() const { return _renderMode; } 
     
    5858//    osg::StateSet * getWallStateSet() { return _wallStateSet.get(); } 
    5959//    /** Get or create the wall StateSet */ 
    60 //    osg::StateSet * getOrCreateWallStateSet()  
    61 //    {  
    62 //        if (_wallStateSet.valid() == false) _wallStateSet = new osg::StateSet;  
    63 //        return _wallStateSet.get();  
     60//    osg::StateSet * getOrCreateWallStateSet() 
     61//    { 
     62//        if (_wallStateSet.valid() == false) _wallStateSet = new osg::StateSet; 
     63//        return _wallStateSet.get(); 
    6464//    } 
    6565//    /** Set the wall StateSet */ 
     
    7272//    /** Set the back StateSet */ 
    7373//    void setBackStateSet(osg::StateSet * backStateSet)  { _backStateSet = backStateSet; } 
    74 //             
    75      
    76     /** Set the Font to use to render the text.   
     74// 
     75 
     76    /** Set the Font to use to render the text. 
    7777      * setFont(0) sets the use of the default font.*/ 
    7878    inline void setFont(Font3D* font=0) { setFont(osg::ref_ptr<Font3D>(font)); }; 
     
    8787    void setFont(const std::string& fontfile); 
    8888 
    89     /** Get the font. Return 0 if default is being used.*/     
     89    /** Get the font. Return 0 if default is being used.*/ 
    9090    const Font3D* getFont() const { return _font.get(); } 
    9191 
    92      
    93      
    94      
     92 
     93 
     94 
    9595    /** Draw the text.*/ 
    9696    virtual void drawImplementation(osg::RenderInfo& renderInfo) const; 
     
    103103 
    104104    /** accept an ConstAttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ 
    105 //    virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const; 
     105    virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const; 
    106106 
    107107    /** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/ 
     
    109109 
    110110    /** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/ 
    111 //    virtual void accept(osg::PrimitiveFunctor& pf) const; 
     111    virtual void accept(osg::PrimitiveFunctor& pf) const; 
    112112 
    113113 
     
    123123    virtual void releaseGLObjects(osg::State* state=0) const; 
    124124 
    125 //    // make Font a friend to allow it set the _font to 0 if the font is  
     125//    // make Font a friend to allow it set the _font to 0 if the font is 
    126126//    // forcefully unloaded. 
    127127    friend class Font3D; 
     
    132132protected: 
    133133 
    134     virtual ~Text3D() {}  
    135      
     134    virtual ~Text3D() {} 
     135 
    136136    void renderPerGlyph(osg::State & state) const; 
    137137    void renderPerFace(osg::State & state) const; 
     
    141141    void computeGlyphRepresentation(); 
    142142    void computePositions(unsigned int contextID) const; 
    143      
     143 
    144144    // ** glyph and other information to render the glyph 
    145145    struct GlyphRenderInfo 
     
    147147        GlyphRenderInfo(Font3D::Glyph3D * glyph, osg::Vec3 & pos) : 
    148148            _glyph(glyph), _position(pos) {} 
    149                      
     149 
    150150        osg::ref_ptr<Font3D::Glyph3D> _glyph; 
    151151        osg::Vec3 _position; 
    152152    }; 
    153      
     153 
    154154    typedef std::vector<GlyphRenderInfo> LineRenderInfo; 
    155     typedef std::vector<LineRenderInfo> TextRenderInfo;     
    156      
     155    typedef std::vector<LineRenderInfo> TextRenderInfo; 
     156 
    157157    TextRenderInfo _textRenderInfo; 
    158158 
     
    160160 
    161161    float _characterDepth; 
    162      
     162 
    163163    RenderMode _renderMode; 
    164      
     164 
    165165    osg::ref_ptr<osg::StateSet> _wallStateSet; 
    166166    osg::ref_ptr<osg::StateSet> _backStateSet; 
  • OpenSceneGraph/trunk/src/osgDB/Registry.cpp

    r9880 r9881  
    319319    addFileExtensionAlias("cef",   "freetype");  // OpenType 
    320320    addFileExtensionAlias("fon",   "freetype");  // Windows bitmap fonts 
    321     addFileExtensionAlias("fnt",   "freetype");    // Windows bitmap fonts 
    322      
     321    addFileExtensionAlias("fnt",   "freetype");  // Windows bitmap fonts 
     322    addFileExtensionAlias("text3d", "freetype"); // use 3D Font instead of 2D Font 
     323 
    323324    // wont't add type1 and type2 until resolve extension collision with Performer binary and ascii files. 
    324325    // addFileExtensionAlias("pfb",   "freetype");  // type1 binary 
  • OpenSceneGraph/trunk/src/osgPlugins/freetype/FreeTypeFont3D.cpp

    r7696 r9881  
    1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield  
     1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
    22 * 
    3  * This library is open source and may be redistributed and/or modified under   
    4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or  
     3 * This library is open source and may be redistributed and/or modified under 
     4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
    55 * (at your option) any later version.  The full license is in LICENSE file 
    66 * included with this distribution, and on the openscenegraph.org website. 
    7  *  
     7 * 
    88 * This library is distributed in the hope that it will be useful, 
    99 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
     10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1111 * OpenSceneGraph Public License for more details. 
    1212*/ 
     
    2121 
    2222#include <osg/Geometry> 
    23 #include <osg/Notify>   
     23#include <osg/Notify> 
    2424#include <osgDB/WriteFile> 
    2525#include <osgUtil/SmoothingVisitor> 
     
    2727 
    2828 
    29 #include <ft2build.h>   
     29#include <ft2build.h> 
    3030#include FT_FREETYPE_H 
    3131 
     
    174174{ 
    175175    Char3DInfo* char3d = (Char3DInfo*)user; 
    176     char3d->cubicTo(  
     176    char3d->cubicTo( 
    177177        osg::Vec2(FT_NUM(control1->x),FT_NUM(control1->y)), 
    178178        osg::Vec2(FT_NUM(control2->x),FT_NUM(control2->y)), 
     
    221221    } 
    222222 
    223     FT_Set_Char_Size( _face, 64*64, 64*64, 600, 600);  
     223    FT_Set_Char_Size( _face, 64*64, 64*64, 600, 600); 
    224224 
    225225    int glyphIndex = FT_Get_Char_Index( _face, 'M' ); 
     
    291291            // not dangling pointers remain 
    292292            freeTypeLibrary->removeFont3DImplmentation(this); 
    293          
     293 
    294294            // free the freetype font face itself 
    295295            FT_Done_Face(_face); 
     
    309309osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode) 
    310310{ 
    311      
    312      
     311 
     312 
    313313    // 
    314     // GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being   
    315     // returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct  
    316     // values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect.   
     314    // GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being 
     315    // returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct 
     316    // values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect. 
    317317    // Microsoft uses a private field for its symbol fonts 
    318318    // 
     
    337337        return 0; 
    338338    } 
    339      
     339 
    340340    // ** init FreeType to describe the glyph 
    341341    Char3DInfo char3d; 
     
    349349    funcs.shift = 0; 
    350350    funcs.delta = 0; 
    351      
     351 
    352352    // ** record description 
    353353    FT_Error _error = FT_Outline_Decompose(&outline, &funcs, &char3d); 
     
    357357        return 0; 
    358358    } 
    359      
     359 
    360360    // ** create geometry for each part of the glyph 
    361361    osg::ref_ptr<osg::Geometry> frontGeo(new osg::Geometry); 
    362362    frontGeo->setVertexArray(char3d.get()->getVertexArray()); 
    363363    frontGeo->setPrimitiveSetList(char3d.get()->getPrimitiveSetList()); 
    364      
     364 
    365365    osg::ref_ptr<osg::Geometry> wallGeo(new osg::Geometry); 
    366366    wallGeo->setVertexArray(frontGeo->getVertexArray()); 
    367      
     367 
    368368    osg::ref_ptr<osg::Geometry> backGeo(new osg::Geometry); 
    369369    backGeo->setVertexArray(frontGeo->getVertexArray()); 
    370          
    371      
    372      
    373     // ** for conveniance. 
     370 
     371 
     372 
     373    // ** for convenience. 
    374374    osg::Vec3Array * vertices = char3d._verts.get(); 
    375      
    376      
    377      
    378     // ** duplicate the vertex for the back face  
     375 
     376 
     377 
     378    // ** duplicate the vertex for the back face 
    379379    // ** with a depth equal to the font depth 
    380380    std::size_t len = vertices->size(); 
    381381    std::size_t dlen = len * 2; 
    382        
     382 
    383383    vertices->reserve(dlen); 
    384         
     384 
    385385    osg::Vec3Array::iterator begin = vertices->begin(); 
    386386    osg::Vec3Array::iterator it = vertices->begin(); 
    387      
     387 
    388388    for (std::size_t i = 0; i != len; ++i, ++it) 
    389389        vertices->push_back(*it); 
    390390//    std::copy(begin, begin + len, begin + len + 1); TOCHECK 
    391      
    392   
     391 
     392 
    393393    // ** and decal new vertices 
    394394    unsigned int depth = _facade->getFontDepth(); 
     
    397397        (*vertices)[i].z() -= depth; 
    398398    } 
    399      
     399 
    400400    osg::Vec3Array::iterator end; 
    401      
     401 
    402402    // ** create wall and back face from the front polygon 
    403     // **  then accumulate them in the apropriate geometry wallGeo and backGeo  
     403    // **  then accumulate them in the appropriate geometry wallGeo and backGeo 
    404404    for (std::size_t i=0; i < frontGeo->getNumPrimitiveSets(); ++i) 
    405405    { 
     
    408408        unsigned int idx = daFront->getFirst(); 
    409409        unsigned int cnt = daFront->getCount(); 
    410          
     410 
    411411        // ** reverse vertices to draw the front face in the CCW 
    412412        std::reverse(begin + idx, begin + idx + cnt); 
    413          
     413 
    414414        // ** create the back polygon 
    415415        osg::ref_ptr<osg::DrawArrays> daBack(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, idx + len, cnt)); 
    416416        backGeo->addPrimitiveSet(daBack.get()); 
    417          
    418          
     417 
     418 
    419419        // ** create the wall triangle strip 
    420         osg::ref_ptr<osg::DrawElementsUInt> deWall(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP));  
     420        osg::ref_ptr<osg::DrawElementsUInt> deWall(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP)); 
    421421        wallGeo->addPrimitiveSet(deWall.get()); 
    422          
     422 
    423423        // **  link triangle strip 
    424424        deWall->push_back(idx + len); 
    425425        for (unsigned int j = 1; j < cnt; ++j) 
    426         {    
     426        { 
    427427            deWall->push_back(idx + cnt - j); 
    428428            deWall->push_back(idx + len + j); 
     
    440440        ts.retessellatePolygons(*frontGeo); 
    441441    } 
    442      
     442 
    443443    { 
    444444        osgUtil::Tessellator ts; 
     
    455455        geode->accept(sm); 
    456456    } 
    457      
    458     // ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list  
     457 
     458    // ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list 
    459459    osgText::Font3D::Glyph3D * glyph3D = new osgText::Font3D::Glyph3D(charcode); 
    460460 
    461461    glyph3D->setVertexArray(dynamic_cast<osg::Vec3Array*>(frontGeo->getVertexArray())); 
    462      
     462    glyph3D->setNormalArray(dynamic_cast<osg::Vec3Array*>(wallGeo->getNormalArray())); 
     463 
    463464    glyph3D->getFrontPrimitiveSetList() = frontGeo->getPrimitiveSetList(); 
    464465    glyph3D->getWallPrimitiveSetList() = wallGeo->getPrimitiveSetList(); 
    465466    glyph3D->getBackPrimitiveSetList() = backGeo->getPrimitiveSetList(); 
    466467 
    467      
     468 
    468469    FT_Glyph_Metrics* metrics = &(_face->glyph->metrics); 
    469470 
     
    476477    glyph3D->setHeight((float)metrics->height / 64.0f); 
    477478 
    478      
     479 
    479480    FT_BBox ftbb; 
    480481    FT_Outline_Get_BBox(&outline, &ftbb); 
     
    484485    long ymin = ft_floor( ftbb.yMin ); 
    485486    long ymax = ft_ceiling( ftbb.yMax ); 
    486          
     487 
    487488    osg::BoundingBox bb(xmin / 64.0f, ymin / 64.0f, 0.0f, xmax / 64.0f, ymax / 64.0f, 0.0f); 
    488      
     489 
    489490    glyph3D->setBoundingBox(bb); 
    490      
     491 
    491492    return glyph3D; 
    492493} 
     
    501502    FT_UInt left = FT_Get_Char_Index( _face, leftcharcode ); 
    502503    FT_UInt right = FT_Get_Char_Index( _face, rightcharcode ); 
    503      
    504     // get the kerning distances.    
     504 
     505    // get the kerning distances. 
    505506    FT_Vector  kerning; 
    506507 
     
    525526} 
    526527 
    527 float FreeTypeFont3D::getScale() const  
    528 {  
    529     return _scale;  
    530 } 
     528float FreeTypeFont3D::getScale() const 
     529{ 
     530    return _scale; 
     531} 
  • OpenSceneGraph/trunk/src/osgPlugins/freetype/ReaderWriterFreeType.cpp

    r8680 r9881  
    1818            supportsExtension("cff","OpenType format"); 
    1919            supportsExtension("cef","OpenType format"); 
    20             supportsExtension("fon","Windows bitmap fonts format"); 
     20            supportsExtension("fon","Windows bitmap fonts format"); 
    2121            supportsExtension("fnt","Windows bitmap fonts format"); 
     22            supportsExtension("text3d","use 3D Font instead of 2D Font"); 
    2223 
    2324            supportsOption("monochrome","Select monochrome font."); 
    2425        } 
    25          
     26 
    2627        virtual const char* className() const { return "FreeType Font Reader/Writer"; } 
    27          
     28 
    2829        static unsigned int getFlags(const osgDB::ReaderWriter::Options* options) 
    2930        { 
     
    3334                flags |= FT_LOAD_MONOCHROME; 
    3435            } 
    35              
     36 
    3637            return flags; 
    3738        } 
     
    3940        virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const 
    4041        { 
    41             std::string ext = osgDB::getLowerCaseFileExtension(file); 
     42            std::string tmpFile = file; 
     43            bool needFont3D = false; 
     44 
     45            std::string ext = osgDB::getLowerCaseFileExtension(tmpFile); 
     46            if (ext == "text3d") 
     47            { 
     48                needFont3D = true; 
     49                tmpFile.erase(tmpFile.size()-7, 7); 
     50                ext = osgDB::getLowerCaseFileExtension(tmpFile); 
     51            } 
     52            else if ((options != NULL) && (options->getPluginData("3D"))) 
     53            { 
     54                needFont3D = true; 
     55            } 
     56 
    4257            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; 
    4358 
    44             std::string fileName = osgDB::findDataFile( file, options ); 
     59            std::string fileName = osgDB::findDataFile( tmpFile, options ); 
    4560            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; 
    46              
     61 
    4762            FreeTypeLibrary* freeTypeLibrary = FreeTypeLibrary::instance(); 
    48             if (!freeTypeLibrary)  
     63            if (!freeTypeLibrary) 
    4964            { 
    5065                osg::notify(osg::WARN)<<"Warning:: cannot create freetype font after freetype library has been deleted."<<std::endl; 
     
    5267            } 
    5368 
    54             if ( (options != NULL) && (options->getPluginData("3D")) ) 
     69            if (needFont3D) 
    5570                return freeTypeLibrary->getFont3D(fileName,0,getFlags(options)); 
    5671            else 
     
    6176        { 
    6277            FreeTypeLibrary* freeTypeLibrary = FreeTypeLibrary::instance(); 
    63             if (!freeTypeLibrary)  
     78            if (!freeTypeLibrary) 
    6479            { 
    6580                osg::notify(osg::WARN)<<"Warning:: cannot create freetype font after freetype library has been deleted."<<std::endl; 
  • OpenSceneGraph/trunk/src/osgText/Font3D.cpp

    r7874 r9881  
    1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield  
     1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
    22 * 
    3  * This library is open source and may be redistributed and/or modified under   
    4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or  
     3 * This library is open source and may be redistributed and/or modified under 
     4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
    55 * (at your option) any later version.  The full license is in LICENSE file 
    66 * included with this distribution, and on the openscenegraph.org website. 
    7  *  
     7 * 
    88 * This library is distributed in the hope that it will be useful, 
    99 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
     10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1111 * OpenSceneGraph Public License for more details. 
    1212*/ 
     
    8787 
    8888    // Not found, return empty string 
    89     osg::notify(osg::WARN)<<"Warning: font file \""<<str<<"\" not found."<<std::endl;     
     89    osg::notify(osg::WARN)<<"Warning: font file \""<<str<<"\" not found."<<std::endl; 
    9090    return std::string(); 
    9191} 
     
    9595    if (filename=="") return 0; 
    9696 
    97     std::string foundFile = findFont3DFile(filename); 
     97    // unsure filename have not .text3d at the end 
     98    std::string tmpFilename; 
     99    std::string text3dExt = ".text3d"; 
     100    std::string ext = osgDB::getFileExtensionIncludingDot(filename); 
     101    if (ext == text3dExt) 
     102        tmpFilename = filename.substr(filename.size() - ext.size(), ext.size()); 
     103    else 
     104        tmpFilename = filename; 
     105 
     106    //search font file 
     107    std::string foundFile = findFont3DFile(tmpFilename); 
    98108    if (foundFile.empty()) return 0; 
    99      
     109 
     110    //unsure filename have .text3d at the end 
     111    foundFile += text3dExt; 
     112 
    100113    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_Font3DFileMutex); 
    101114 
     
    105118        localOptions = new osgDB::ReaderWriter::Options; 
    106119        localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS); 
    107         // ** HACK to load Font3D instead of Font 
    108         localOptions->setPluginData("3D", (void*) 1); 
    109     } 
    110     else 
    111     { 
    112         userOptions->setPluginData("3D", (void*) 1); 
    113120    } 
    114121 
    115122    osg::Object* object = osgDB::readObjectFile(foundFile, userOptions ? userOptions : localOptions.get()); 
    116      
     123 
    117124    // if the object is a font then return it. 
    118125    osgText::Font3D* font3D = dynamic_cast<osgText::Font3D*>(object); 
     
    143150    osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension("ttf"); 
    144151    if (reader == 0) return 0; 
    145      
     152 
    146153    osgDB::ReaderWriter::ReadResult rr = reader->readObject(stream, userOptions ? userOptions : localOptions.get()); 
    147154    if (rr.error()) 
     
    151158    } 
    152159    if (!rr.validObject()) return 0; 
    153      
     160 
    154161    osg::Object *object = rr.takeObject(); 
    155162 
     
    167174    if (filename=="") return 0; 
    168175 
    169     std::string foundFile = findFont3DFile(filename); 
     176    std::string tmpFilename; 
     177    std::string text3dExt = ".text3d"; 
     178    std::string ext = osgDB::getFileExtensionIncludingDot(filename); 
     179    if (ext == text3dExt) 
     180        tmpFilename = filename.substr(0, filename.size() - ext.size()); 
     181    else 
     182        tmpFilename = filename; 
     183 
     184    std::string foundFile = findFont3DFile(tmpFilename); 
    170185    if (foundFile.empty()) return 0; 
    171      
     186 
     187    foundFile += text3dExt; 
     188 
    172189    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_Font3DFileMutex); 
    173190 
     
    177194        localOptions = new osgDB::ReaderWriter::Options; 
    178195        localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS); 
    179         // ** HACK to load Font3D instead of Font 
    180         localOptions->setPluginData("3D", (void*) 1); 
    181     } 
    182     else 
    183     { 
    184         userOptions->setPluginData("3D", (void*) 1); 
    185196    } 
    186197 
    187198    osg::ref_ptr<osg::Object> object = osgDB::readRefObjectFile(foundFile, userOptions ? userOptions : localOptions.get()); 
    188      
     199 
    189200    // if the object is a font then return it. 
    190201    osgText::Font3D* font3D = dynamic_cast<osgText::Font3D*>(object.get()); 
     
    213224    osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension("ttf"); 
    214225    if (reader == 0) return 0; 
    215      
     226 
    216227    osgDB::ReaderWriter::ReadResult rr = reader->readObject(stream, userOptions ? userOptions : localOptions.get()); 
    217228    if (rr.error()) 
     
    268279Font3D::Glyph3D* Font3D::getGlyph(unsigned int charcode) 
    269280{ 
    270     Glyph3D * glyph3D = NULL;  
    271      
     281    Glyph3D * glyph3D = NULL; 
     282 
    272283    Glyph3DMap::iterator itr = _glyph3DMap.find(charcode); 
    273284    if (itr!=_glyph3DMap.end()) glyph3D = itr->second.get(); 
    274      
     285 
    275286    else if (_implementation.valid()) 
    276287    { 
     
    278289        if (glyph3D) _glyph3DMap[charcode] = glyph3D; 
    279290    } 
    280      
     291 
    281292    return glyph3D; 
    282293} 
     
    285296{ 
    286297    Glyph3DMap::iterator it,end = _glyph3DMap.end(); 
    287      
     298 
    288299    for (it=_glyph3DMap.begin(); it!=end; ++it) 
    289300        it->second->setThreadSafeRefUnref(threadSafe); 
  • OpenSceneGraph/trunk/src/osgText/Text3D.cpp

    r8868 r9881  
    1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield  
     1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
    22 * 
    3  * This library is open source and may be redistributed and/or modified under   
    4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or  
     3 * This library is open source and may be redistributed and/or modified under 
     4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
    55 * (at your option) any later version.  The full license is in LICENSE file 
    66 * included with this distribution, and on the openscenegraph.org website. 
    7  *  
     7 * 
    88 * This library is distributed in the hope that it will be useful, 
    99 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
     10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1111 * OpenSceneGraph Public License for more details. 
    1212*/ 
     
    1414#include <osgText/Text3D> 
    1515#include <osg/io_utils> 
    16 namespace osgText  
     16namespace osgText 
    1717{ 
    1818 
     
    3333} 
    3434 
    35 //void Text3D::accept(osg::Drawable::ConstAttributeFunctor& af) const 
    36 //{ 
    37 //    TODO 
    38 //} 
    39  
    40 //void Text3D::accept(osg::PrimitiveFunctor& /*pf*/) const 
    41 //{ 
    42 //    TODO  
    43 //} 
     35void Text3D::accept(osg::Drawable::ConstAttributeFunctor& af) const 
     36{ 
     37    // ** for each line, do ... 
     38    TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end(); 
     39    for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) 
     40    { 
     41        // ** for each glyph in the line, do ... 
     42        LineRenderInfo::const_iterator it, end = itLine->end(); 
     43        for (it = itLine->begin(); it!=end; ++it) 
     44        { 
     45            // ** apply the vertex array 
     46            af.apply(osg::Drawable::VERTICES, it->_glyph->getVertexArray()->size(), &(it->_glyph->getVertexArray()->front())); 
     47        } 
     48    } 
     49} 
     50void Text3D::accept(osg::PrimitiveFunctor& pf) const 
     51{ 
     52    // ** for each line, do ... 
     53    TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end(); 
     54    for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) 
     55    { 
     56        // ** for each glyph in the line, do ... 
     57        LineRenderInfo::const_iterator it, end = itLine->end(); 
     58        for (it = itLine->begin(); it!=end; ++it) 
     59        { 
     60            pf.setVertexArray(it->_glyph->getVertexArray()->size(),&(it->_glyph->getVertexArray()->front())); 
     61 
     62            // ** render the front face of the glyph 
     63            osg::Geometry::PrimitiveSetList & pslFront = it->_glyph->getFrontPrimitiveSetList(); 
     64            for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr) 
     65            { 
     66                (*itr)->accept(pf); 
     67            } 
     68 
     69            // ** render the wall face of the glyph 
     70            osg::Geometry::PrimitiveSetList & pslWall = it->_glyph->getWallPrimitiveSetList(); 
     71            for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslWall.begin(), end=pslWall.end(); itr!=end; ++itr) 
     72            { 
     73                (*itr)->accept(pf); 
     74            } 
     75 
     76            // ** render the back face of the glyph 
     77            osg::Geometry::PrimitiveSetList & pslBack = it->_glyph->getBackPrimitiveSetList(); 
     78            for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr) 
     79            { 
     80                (*itr)->accept(pf); 
     81            } 
     82        } 
     83    } 
     84} 
    4485 
    4586void Text3D::setFont(osg::ref_ptr<Font3D> font) 
    46 {  
     87{ 
    4788    _font = font; 
    48      
     89 
    4990    computeGlyphRepresentation(); 
    5091} 
    5192 
    5293void Text3D::setFont(const std::string & fontfile) 
    53 {  
     94{ 
    5495    setFont(readRefFont3DFile(fontfile)); 
    5596} 
     
    76117    float maximumHeight = _maximumHeight / _font->getScale(); 
    77118    float maximumWidth = _maximumWidth / _font->getScale(); 
    78      
     119 
    79120    for(bool outOfSpace=false;lastChar!=last;++lastChar) 
    80121    { 
    81122        unsigned int charcode = *lastChar; 
    82          
     123 
    83124        if (charcode=='\n') 
    84125        { 
     
    90131        { 
    91132            const osg::BoundingBox & bb = glyph->getBoundingBox(); 
    92              
     133 
    93134            // adjust cursor position w.r.t any kerning. 
    94135            if (previous_charcode) 
    95136            { 
    96                  
     137 
    97138                if (_layout == RIGHT_TO_LEFT) 
    98139                { 
    99140                    cursor.x() -= glyph->getHorizontalAdvance(); 
    100141                } 
    101                  
     142 
    102143                if (kerning) 
    103144                { 
     
    120161            } 
    121162            else 
    122             {  
     163            { 
    123164                switch (_layout) 
    124165                { 
     
    136177                        break; 
    137178                } 
    138                  
    139             } 
    140              
    141              
     179 
     180            } 
     181 
     182 
    142183 
    143184            switch(_layout) 
     
    159200                break; 
    160201            } 
    161              
     202 
    162203            // => word boundary detection & wrapping 
    163204            if (outOfSpace) break; 
     
    176217 
    177218    } 
    178      
     219 
    179220    // word boundary detection & wrapping 
    180221    if (lastChar!=last) 
    181222    { 
    182         if (deliminatorSet.count(*lastChar)==0)  
     223        if (deliminatorSet.count(*lastChar)==0) 
    183224        { 
    184225            String::iterator lastValidChar = lastChar; 
     
    186227            { 
    187228                --lastValidChar; 
    188                  
     229 
    189230                //Substract off glyphs from the cursor position (to correctly center text) 
    190231                Font3D::Glyph3D* glyph = _font->getGlyph(*lastValidChar); 
     
    199240                } 
    200241            } 
    201              
     242 
    202243            if (first!=lastValidChar) 
    203244            { 
     
    214255{ 
    215256    if (_font.valid() == false) return; 
    216      
     257 
    217258    _textRenderInfo.clear(); 
    218259    _lineCount = 0; 
    219      
    220     if (_text.empty())  
     260 
     261    if (_text.empty()) 
    221262    { 
    222263        _textBB.set(0,0,0, 0,0,0);//no size text 
     
    224265        return; 
    225266    } 
    226      
     267 
    227268    // initialize bounding box, it will be expanded during glyph position calculation 
    228269    _textBB.init(); 
     
    232273    osg::Vec2 local(0.0f,0.0f); 
    233274    osg::Vec2 startOffset(0.0f,0.0f); 
    234      
     275 
    235276    unsigned int previous_charcode = 0; 
    236277    unsigned int linelength = 0; 
    237278    bool kerning = true; 
    238      
     279 
    239280    unsigned int lineNumber = 0; 
    240281 
    241    
     282 
    242283 
    243284    for(String::iterator itr=_text.begin(); itr!=_text.end(); ) 
     
    245286        _textRenderInfo.resize(lineNumber + 1); 
    246287        LineRenderInfo & currentLineRenderInfo = _textRenderInfo.back(); 
    247          
     288 
    248289        // record the start of the current line 
    249290        String::iterator startOfLine_itr = itr; 
     
    252293        osg::Vec2 endOfLine_coords(cursor); 
    253294        String::iterator endOfLine_itr = computeLastCharacterOnLine(endOfLine_coords, itr,_text.end()); 
    254          
    255         // ** position the cursor function to the Layout and the alignement  
     295 
     296        // ** position the cursor function to the Layout and the alignement 
    256297        TextBase::positionCursor(endOfLine_coords, cursor, (unsigned int) (endOfLine_itr - startOfLine_itr)); 
    257298 
    258          
     299 
    259300        if (itr!=endOfLine_itr) 
    260301        { 
     
    267308                { 
    268309                    const osg::BoundingBox & bb = glyph->getBoundingBox(); 
    269                      
     310 
    270311                    // adjust cursor position w.r.t any kerning. 
    271312                    if (previous_charcode) 
     
    275316                            cursor.x() -= glyph->getHorizontalAdvance(); 
    276317                        } 
    277                          
     318 
    278319                        if (kerning) 
    279320                        { 
     
    296337                    } 
    297338                    else 
    298                     {  
     339                    { 
    299340                        switch (_layout) 
    300341                        { 
     
    315356                            } 
    316357                        } 
    317                          
     358 
    318359                    } 
    319360 
    320361                    local = cursor; 
    321                      
     362 
    322363                    if (_layout==VERTICAL) 
    323364                    { 
     
    325366                        local.y() += -glyph->getVerticalBearing().y(); 
    326367                    } 
    327                       
    328                      
    329                      
     368 
     369 
     370 
    330371                    // move the cursor onto the next character. 
    331372                    // also expand bounding box 
     
    345386                            _textBB.expandBy(osg::Vec3(cursor.x()+bb.xMax(), cursor.y() + bb.yMax(), 0.0f)); //upper right corner 
    346387                            _textBB.expandBy(osg::Vec3(cursor.x()+bb.xMin(), cursor.y()+bb.yMin(), 0.0f)); //lower left corner 
    347                              
     388 
    348389                            break; 
    349390                    } 
    350                      
     391 
    351392                    osg::Vec3 pos = osg::Vec3(local.x(), local.y(), 0.0f); 
    352393                    currentLineRenderInfo.push_back(Text3D::GlyphRenderInfo(glyph, pos)); 
    353394 
    354                      
     395 
    355396                    previous_charcode = charcode; 
    356397                } 
     
    361402            ++itr; 
    362403        } 
    363                                  
     404 
    364405        if (itr!=_text.end()) 
    365406        { 
     
    367408            if (*itr=='\n') ++itr; 
    368409        } 
    369                  
     410 
    370411        // move to new line. 
    371412        switch(_layout) 
     
    395436    } 
    396437    _textBB.expandBy(0.0f,0.0f,-1); 
    397      
     438 
    398439    TextBase::computePositions(); 
    399440} 
    400  
    401  
    402441 
    403442osg::BoundingBox Text3D::computeBound() const 
     
    411450            osg::Matrix& matrix = _autoTransformCache[i]._matrix; 
    412451            bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*matrix); 
    413 //          bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*matrix); 
    414452            bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMax())*matrix); 
    415 //          bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*matrix); 
    416         } 
    417     } 
    418      
     453        } 
     454    } 
     455 
    419456    return bbox; 
    420457} 
    421458 
    422  
    423  
    424  
    425  
    426  
    427  
    428459void Text3D::computePositions(unsigned int contextID) const 
    429460{ 
    430461    if (_font.valid() == false) return; 
    431      
     462 
    432463    switch(_alignment) 
    433464    { 
     
    447478    case CENTER_BASE_LINE:  _offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,0.0f,0.0f); break; 
    448479    case RIGHT_BASE_LINE:  _offset.set(_textBB.xMax(),0.0f,0.0f); break; 
    449      
     480 
    450481    case LEFT_BOTTOM_BASE_LINE:  _offset.set(0.0f,-_characterHeight*(_lineCount-1),0.0f); break; 
    451482    case CENTER_BOTTOM_BASE_LINE:  _offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,-_characterHeight*(_lineCount-1),0.0f); break; 
    452483    case RIGHT_BOTTOM_BASE_LINE:  _offset.set(_textBB.xMax(),-_characterHeight*(_lineCount-1),0.0f); break; 
    453484    } 
    454      
     485 
    455486    AutoTransformCache& atc = _autoTransformCache[contextID]; 
    456487    osg::Matrix& matrix = atc._matrix; 
    457488 
    458      
     489 
    459490    float scale = _font->getScale(); 
    460491    osg::Vec3 scaleVec(scale * _characterHeight, scale * _characterHeight / _characterAspectRatio, _characterDepth); 
     
    464495    matrix.postMultTranslate(_position); 
    465496 
    466      
     497 
    467498    _normal = osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),matrix); 
    468499    _normal.normalize(); 
    469500 
    470     const_cast<Text3D*>(this)->dirtyBound();     
     501    const_cast<Text3D*>(this)->dirtyBound(); 
    471502} 
    472503 
     
    475506    osg::State & state = *renderInfo.getState(); 
    476507    unsigned int contextID = state.getContextID(); 
    477      
    478      
     508 
     509 
    479510    // ** save the previous modelview matrix 
    480511    osg::ref_ptr<osg::RefMatrix> previous(new osg::RefMatrix(state.getModelViewMatrix())); 
     
    485516    // ** mult previous by the modelview for this context 
    486517    modelview->postMult(*previous.get()); 
    487     
     518 
    488519    // ** apply this new modelview matrix 
    489520    state.applyModelViewMatrix(modelview.get()); 
    490      
    491      
     521 
     522 
    492523    if (_drawMode & TEXT) 
    493524    { 
    494525        renderInfo.getState()->disableAllVertexArrays(); 
    495          
     526 
    496527        glPushAttrib(GL_TRANSFORM_BIT); 
    497528        glEnable(GL_RESCALE_NORMAL); 
    498          
     529 
    499530        switch(_renderMode) 
    500531        { 
     
    503534            default:        renderPerGlyph(*renderInfo.getState());  break; 
    504535        } 
    505          
     536 
    506537        glPopAttrib(); 
    507538    } 
     
    515546            osg::Vec3 c110(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMax())); 
    516547            osg::Vec3 c010(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMax())); 
    517          
     548 
    518549            osg::Vec3 c001(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())); 
    519550            osg::Vec3 c101(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())); 
    520551            osg::Vec3 c111(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())); 
    521552            osg::Vec3 c011(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())); 
    522          
     553 
    523554            glBegin(GL_LINE_LOOP); 
    524555                glVertex3fv(c000.ptr()); 
     
    527558                glVertex3fv(c010.ptr()); 
    528559            glEnd(); 
    529              
     560 
    530561            glBegin(GL_LINE_LOOP); 
    531562                glVertex3fv(c001.ptr()); 
     
    534565                glVertex3fv(c101.ptr()); 
    535566            glEnd(); 
    536              
     567 
    537568            glBegin(GL_LINES); 
    538569                glVertex3fv(c000.ptr()); 
    539570                glVertex3fv(c001.ptr()); 
    540                  
     571 
    541572                glVertex3fv(c100.ptr()); 
    542573                glVertex3fv(c101.ptr()); 
    543                  
     574 
    544575                glVertex3fv(c110.ptr()); 
    545576                glVertex3fv(c111.ptr()); 
    546                  
     577 
    547578                glVertex3fv(c010.ptr()); 
    548579                glVertex3fv(c011.ptr()); 
    549580            glEnd(); 
    550581        } 
    551     }     
     582    } 
    552583 
    553584    if (_drawMode & ALIGNMENT) 
     
    566597            glVertex3fv(vb.ptr()); 
    567598        glEnd(); 
    568          
     599 
    569600    } 
    570601 
     
    573604} 
    574605 
    575  
    576  
    577606void Text3D::renderPerGlyph(osg::State & state) const 
    578 {    
     607{ 
    579608    // ** for each line, do ... 
    580609    TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end(); 
     
    585614        for (it = itLine->begin(); it!=end; ++it) 
    586615        { 
    587              
     616 
    588617            glPushMatrix(); 
    589618 
    590619            glTranslatef(it->_position.x(), it->_position.y(), it->_position.z()); 
    591             
     620 
    592621            // ** apply the vertex array 
    593622            state.setVertexPointer(it->_glyph->getVertexArray()); 
    594              
     623 
    595624            // ** render the front face of the glyph 
    596625            glNormal3f(0.0f,0.0f,1.0f); 
    597              
     626 
    598627            osg::Geometry::PrimitiveSetList & pslFront = it->_glyph->getFrontPrimitiveSetList(); 
    599628            for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr) 
    600629            { 
    601                  
    602630                (*itr)->draw(state, false); 
    603631            } 
    604              
     632 
    605633            // ** render the wall face of the glyph 
    606634            state.setNormalPointer(it->_glyph->getNormalArray()); 
     
    610638                (*itr)->draw(state, false); 
    611639            } 
    612              
     640            state.disableNormalPointer(); 
     641 
    613642            // ** render the back face of the glyph 
    614643            glNormal3f(0.0f,0.0f,-1.0f); 
    615                          
     644 
    616645            osg::Geometry::PrimitiveSetList & pslBack = it->_glyph->getBackPrimitiveSetList(); 
    617646            for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr) 
     
    619648                (*itr)->draw(state, false); 
    620649            } 
    621              
     650 
    622651            glPopMatrix(); 
    623652        } 
     
    629658    // ** render all front faces 
    630659    glNormal3f(0.0f,0.0f,1.0f); 
    631      
     660 
    632661    TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end(); 
    633662    for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) 
     
    635664        // ** for each glyph in the line, do ... 
    636665        LineRenderInfo::const_iterator it, end = itLine->end(); 
    637         for (it = itLine->begin(); it!=end; ++it)    
     666        for (it = itLine->begin(); it!=end; ++it) 
    638667        { 
    639668            glPushMatrix(); 
    640669            glTranslatef(it->_position.x(), it->_position.y(), it->_position.z()); 
    641670            state.setVertexPointer(it->_glyph->getVertexArray()); 
    642              
     671 
    643672            // ** render the front face of the glyph 
    644673            osg::Geometry::PrimitiveSetList & psl = it->_glyph->getFrontPrimitiveSetList(); 
     
    650679        } 
    651680    } 
    652      
     681 
    653682 
    654683    // ** render all wall face of the text 
     
    663692            state.setVertexPointer(it->_glyph->getVertexArray()); 
    664693            state.setNormalPointer(it->_glyph->getNormalArray()); 
    665              
     694 
    666695            osg::Geometry::PrimitiveSetList & psl = it->_glyph->getWallPrimitiveSetList(); 
    667696            for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr) 
     
    673702    } 
    674703 
    675      
     704 
    676705    // ** render all back face of the text 
    677706    glNormal3f(0.0f,0.0f,-1.0f); 
    678                  
     707 
    679708    for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) 
    680709    { 
     
    686715            glTranslatef(it->_position.x(), it->_position.y(), it->_position.z()); 
    687716            state.setVertexPointer(it->_glyph->getVertexArray()); 
    688              
     717 
    689718            // ** render the back face of the glyph 
    690719            osg::Geometry::PrimitiveSetList & psl = it->_glyph->getBackPrimitiveSetList(); 
     
    710739{ 
    711740    TextBase::resizeGLObjectBuffers(maxSize); 
    712      
     741 
    713742    if (_font.valid()) _font->resizeGLObjectBuffers(maxSize); 
    714743} 
     
    717746{ 
    718747    TextBase::releaseGLObjects(state); 
    719      
     748 
    720749    if (_font.valid()) _font->releaseGLObjects(state); 
    721750}