Show
Ignore:
Timestamp:
03/10/09 11:56:00 (5 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.
"

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • 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}