Show
Ignore:
Timestamp:
02/25/08 14:07:37 (6 years ago)
Author:
robert
Message:

Reverted back to previous version of osgtext

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgtext/osgtext.cpp

    r7874 r7875  
    3737 
    3838 
    39  
    40  
    41  
    42  
     39osg::Group* createHUDText() 
     40{ 
     41 
     42    osg::Group* rootNode = new osg::Group; 
     43 
     44    osgText::Font* font = osgText::readFontFile("fonts/arial.ttf"); 
     45 
     46    osg::Geode* geode  = new osg::Geode; 
     47    rootNode->addChild(geode); 
     48 
     49    float windowHeight = 1024.0f; 
     50    float windowWidth = 1280.0f; 
     51    float margin = 50.0f; 
     52 
     53 
     54//////////////////////////////////////////////////////////////////////////////////////////////////////// 
     55//     
     56// Examples of how to set up different text layout 
     57// 
     58 
     59    osg::Vec4 layoutColor(1.0f,1.0f,0.0f,1.0f); 
     60    float layoutCharacterSize = 20.0f;     
     61     
     62    { 
     63        osgText::Text* text = new osgText::Text; 
     64        text->setFont(font); 
     65        text->setColor(layoutColor); 
     66        text->setCharacterSize(layoutCharacterSize); 
     67        text->setPosition(osg::Vec3(margin,windowHeight-margin,0.0f)); 
     68 
     69        // the default layout is left to right, typically used in languages 
     70        // originating from europe such as English, French, German, Spanish etc.. 
     71        text->setLayout(osgText::Text::LEFT_TO_RIGHT); 
     72 
     73        text->setText("text->setLayout(osgText::Text::LEFT_TO_RIGHT);"); 
     74        geode->addDrawable(text); 
     75    } 
     76 
     77    { 
     78        osgText::Text* text = new osgText::Text; 
     79        text->setFont(font); 
     80        text->setColor(layoutColor); 
     81        text->setCharacterSize(layoutCharacterSize); 
     82        text->setPosition(osg::Vec3(windowWidth-margin,windowHeight-margin,0.0f)); 
     83 
     84        // right to left layouts would be used for hebrew or arabic fonts. 
     85        text->setLayout(osgText::Text::RIGHT_TO_LEFT); 
     86        text->setAlignment(osgText::Text::RIGHT_BASE_LINE); 
     87 
     88        text->setText("text->setLayout(osgText::Text::RIGHT_TO_LEFT);"); 
     89        geode->addDrawable(text); 
     90    } 
     91 
     92    { 
     93        osgText::Text* text = new osgText::Text; 
     94        text->setFont(font); 
     95        text->setColor(layoutColor); 
     96        text->setPosition(osg::Vec3(margin,windowHeight-margin,0.0f)); 
     97        text->setCharacterSize(layoutCharacterSize); 
     98 
     99        // vertical font layout would be used for asian fonts. 
     100        text->setLayout(osgText::Text::VERTICAL); 
     101 
     102        text->setText("text->setLayout(osgText::Text::VERTICAL);"); 
     103        geode->addDrawable(text); 
     104    } 
     105     
     106     
     107//////////////////////////////////////////////////////////////////////////////////////////////////////// 
     108//     
     109// Examples of how to set up different font resolution 
     110// 
     111 
     112    osg::Vec4 fontSizeColor(0.0f,1.0f,1.0f,1.0f); 
     113    float fontSizeCharacterSize = 30; 
     114     
     115    osg::Vec3 cursor = osg::Vec3(margin*2,windowHeight-margin*2,0.0f); 
     116     
     117    { 
     118        osgText::Text* text = new osgText::Text; 
     119        text->setFont(font); 
     120        text->setColor(fontSizeColor); 
     121        text->setCharacterSize(fontSizeCharacterSize); 
     122        text->setPosition(cursor); 
     123         
     124        // use text that uses 10 by 10 texels as a target resolution for fonts. 
     125        text->setFontResolution(10,10); // blocky but small texture memory usage 
     126         
     127        text->setText("text->setFontResolution(10,10); // blocky but small texture memory usage"); 
     128        geode->addDrawable(text); 
     129    } 
     130     
     131    cursor.y() -= fontSizeCharacterSize; 
     132    { 
     133        osgText::Text* text = new osgText::Text; 
     134        text->setFont(font); 
     135        text->setColor(fontSizeColor); 
     136        text->setCharacterSize(fontSizeCharacterSize); 
     137        text->setPosition(cursor); 
     138         
     139        // use text that uses 20 by 20 texels as a target resolution for fonts. 
     140        text->setFontResolution(20,20); // smoother but higher texture memory usage (but still quite low). 
     141         
     142        text->setText("text->setFontResolution(20,20); // smoother but higher texture memory usage (but still quite low)."); 
     143        geode->addDrawable(text); 
     144    } 
     145     
     146    cursor.y() -= fontSizeCharacterSize; 
     147    { 
     148        osgText::Text* text = new osgText::Text; 
     149        text->setFont(font); 
     150        text->setColor(fontSizeColor); 
     151        text->setCharacterSize(fontSizeCharacterSize); 
     152        text->setPosition(cursor); 
     153         
     154        // use text that uses 40 by 40 texels as a target resolution for fonts. 
     155        text->setFontResolution(40,40); // even smoother but again higher texture memory usage. 
     156         
     157        text->setText("text->setFontResolution(40,40); // even smoother but again higher texture memory usage."); 
     158        geode->addDrawable(text); 
     159    } 
     160 
     161 
     162//////////////////////////////////////////////////////////////////////////////////////////////////////// 
     163//     
     164// Examples of how to set up different sized text 
     165// 
     166 
     167    osg::Vec4 characterSizeColor(1.0f,0.0f,1.0f,1.0f); 
     168     
     169    cursor.y() -= fontSizeCharacterSize*2.0f; 
     170     
     171    { 
     172        osgText::Text* text = new osgText::Text; 
     173        text->setFont(font); 
     174        text->setColor(characterSizeColor); 
     175        text->setFontResolution(20,20); 
     176        text->setPosition(cursor); 
     177         
     178        // use text that is 20 units high. 
     179        text->setCharacterSize(20); // small 
     180         
     181        text->setText("text->setCharacterSize(20.0f); // small"); 
     182        geode->addDrawable(text); 
     183    } 
     184     
     185    cursor.y() -= 30.0f; 
     186    { 
     187        osgText::Text* text = new osgText::Text; 
     188        text->setFont(font); 
     189        text->setColor(characterSizeColor); 
     190        text->setFontResolution(30,30); 
     191        text->setPosition(cursor); 
     192         
     193        // use text that is 30 units high. 
     194        text->setCharacterSize(30.0f); // medium 
     195         
     196        text->setText("text->setCharacterSize(30.0f); // medium"); 
     197        geode->addDrawable(text); 
     198    } 
     199     
     200    cursor.y() -= 50.0f; 
     201    { 
     202        osgText::Text* text = new osgText::Text; 
     203        text->setFont(font); 
     204        text->setColor(characterSizeColor); 
     205        text->setFontResolution(40,40); 
     206        text->setPosition(cursor); 
     207         
     208        // use text that is 60 units high. 
     209        text->setCharacterSize(60.0f); // large 
     210         
     211        text->setText("text->setCharacterSize(60.0f); // large"); 
     212        geode->addDrawable(text); 
     213    } 
     214 
     215 
     216//////////////////////////////////////////////////////////////////////////////////////////////////////// 
     217//     
     218// Examples of how to set up different alignments 
     219// 
     220 
     221    osg::Vec4 alignmentSizeColor(0.0f,1.0f,0.0f,1.0f); 
     222    float alignmentCharacterSize = 25.0f; 
     223    cursor.x() = 640; 
     224    cursor.y() = margin*4.0f; 
     225     
     226    typedef std::pair<osgText::Text::AlignmentType,std::string> AlignmentPair; 
     227    typedef std::vector<AlignmentPair> AlignmentList; 
     228    AlignmentList alignmentList; 
     229    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_TOP,"text->setAlignment(\nosgText::Text::LEFT_TOP);")); 
     230    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_CENTER,"text->setAlignment(\nosgText::Text::LEFT_CENTER);")); 
     231    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_BOTTOM,"text->setAlignment(\nosgText::Text::LEFT_BOTTOM);")); 
     232    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_TOP,"text->setAlignment(\nosgText::Text::CENTER_TOP);")); 
     233    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_CENTER,"text->setAlignment(\nosgText::Text::CENTER_CENTER);")); 
     234    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_BOTTOM,"text->setAlignment(\nosgText::Text::CENTER_BOTTOM);")); 
     235    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_TOP,"text->setAlignment(\nosgText::Text::RIGHT_TOP);")); 
     236    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_CENTER,"text->setAlignment(\nosgText::Text::RIGHT_CENTER);")); 
     237    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_BOTTOM,"text->setAlignment(\nosgText::Text::RIGHT_BOTTOM);")); 
     238    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_BASE_LINE,"text->setAlignment(\nosgText::Text::LEFT_BASE_LINE);")); 
     239    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_BASE_LINE,"text->setAlignment(\nosgText::Text::CENTER_BASE_LINE);")); 
     240    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_BASE_LINE,"text->setAlignment(\nosgText::Text::RIGHT_BASE_LINE);")); 
     241    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_BOTTOM_BASE_LINE,"text->setAlignment(\nosgText::Text::LEFT_BOTTOM_BASE_LINE);")); 
     242    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_BOTTOM_BASE_LINE,"text->setAlignment(\nosgText::Text::CENTER_BOTTOM_BASE_LINE);")); 
     243    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_BOTTOM_BASE_LINE,"text->setAlignment(\nosgText::Text::RIGHT_BOTTOM_BASE_LINE);")); 
     244 
     245 
     246    osg::Sequence* sequence = new osg::Sequence; 
     247    { 
     248        for(AlignmentList::iterator itr=alignmentList.begin(); 
     249            itr!=alignmentList.end(); 
     250            ++itr) 
     251        { 
     252            osg::Geode* alignmentGeode = new osg::Geode; 
     253            sequence->addChild(alignmentGeode); 
     254            sequence->setTime(sequence->getNumChildren(), 1.0f); 
     255 
     256            osgText::Text* text = new osgText::Text; 
     257            text->setFont(font); 
     258            text->setColor(alignmentSizeColor); 
     259            text->setCharacterSize(alignmentCharacterSize); 
     260            text->setPosition(cursor); 
     261            text->setDrawMode(osgText::Text::TEXT|osgText::Text::ALIGNMENT|osgText::Text::BOUNDINGBOX); 
     262             
     263            text->setAlignment(itr->first); 
     264            text->setText(itr->second); 
     265             
     266            alignmentGeode->addDrawable(text); 
     267 
     268 
     269        } 
     270         
     271    } 
     272 
     273    sequence->setMode(osg::Sequence::START); 
     274    sequence->setInterval(osg::Sequence::LOOP, 0, -1); 
     275    sequence->setDuration(1.0f, -1); 
     276     
     277    rootNode->addChild(sequence); 
     278 
     279 
     280//////////////////////////////////////////////////////////////////////////////////////////////////////// 
     281//     
     282// Examples of how to set up different fonts... 
     283// 
     284 
     285    cursor.x() = margin*2.0f; 
     286    cursor.y() = margin*2.0f; 
     287     
     288    osg::Vec4 fontColor(1.0f,0.5f,0.0f,1.0f); 
     289    float fontCharacterSize = 20.0f; 
     290    float spacing = 40.0f; 
     291     
     292    { 
     293        osgText::Text* text = new osgText::Text; 
     294        text->setColor(fontColor); 
     295        text->setPosition(cursor); 
     296        text->setCharacterSize(fontCharacterSize); 
     297         
     298        text->setFont(0); 
     299        text->setText("text->setFont(0); // inbuilt font."); 
     300        geode->addDrawable(text); 
     301 
     302        cursor.x() = text->getBound().xMax() + spacing ; 
     303    } 
     304     
     305    { 
     306        osgText::Font* arial = osgText::readFontFile("fonts/arial.ttf"); 
     307 
     308        osgText::Text* text = new osgText::Text; 
     309        text->setColor(fontColor); 
     310        text->setPosition(cursor); 
     311        text->setCharacterSize(fontCharacterSize); 
     312         
     313        text->setFont(arial); 
     314        text->setText(arial!=0? 
     315                      "text->setFont(\"fonts/arial.ttf\");": 
     316                      "unable to load \"fonts/arial.ttf\""); 
     317        geode->addDrawable(text); 
     318 
     319        cursor.x() = text->getBound().xMax() + spacing ; 
     320    } 
     321     
     322    { 
     323        osgText::Font* times = osgText::readFontFile("fonts/times.ttf"); 
     324 
     325        osgText::Text* text = new osgText::Text; 
     326        text->setColor(fontColor); 
     327        text->setPosition(cursor); 
     328        text->setCharacterSize(fontCharacterSize); 
     329         
     330        geode->addDrawable(text); 
     331        text->setFont(times); 
     332        text->setText(times!=0? 
     333                      "text->setFont(\"fonts/times.ttf\");": 
     334                      "unable to load \"fonts/times.ttf\""); 
     335 
     336        cursor.x() = text->getBound().xMax() + spacing ; 
     337    } 
     338     
     339    cursor.x() = margin*2.0f; 
     340    cursor.y() = margin; 
     341 
     342    { 
     343        osgText::Font* dirtydoz = osgText::readFontFile("fonts/dirtydoz.ttf"); 
     344 
     345        osgText::Text* text = new osgText::Text; 
     346        text->setColor(fontColor); 
     347        text->setPosition(cursor); 
     348        text->setCharacterSize(fontCharacterSize); 
     349         
     350        text->setFont(dirtydoz); 
     351        text->setText(dirtydoz!=0? 
     352                      "text->setFont(\"fonts/dirtydoz.ttf\");": 
     353                      "unable to load \"fonts/dirtydoz.ttf\""); 
     354        geode->addDrawable(text); 
     355 
     356        cursor.x() = text->getBound().xMax() + spacing ; 
     357    } 
     358     
     359    { 
     360        osgText::Font* fudd = osgText::readFontFile("fonts/fudd.ttf"); 
     361     
     362        osgText::Text* text = new osgText::Text; 
     363        text->setColor(fontColor); 
     364        text->setPosition(cursor); 
     365        text->setCharacterSize(fontCharacterSize); 
     366         
     367        text->setFont(fudd); 
     368        text->setText(fudd!=0? 
     369                      "text->setFont(\"fonts/fudd.ttf\");": 
     370                      "unable to load \"fonts/fudd.ttf\""); 
     371        geode->addDrawable(text); 
     372 
     373        cursor.x() = text->getBound().xMax() + spacing ; 
     374    } 
     375             
     376    return rootNode;     
     377} 
     378 
     379 
     380 
     381 
     382// create text which sits in 3D space such as would be inserted into a normal model 
     383osg::Group* create3DText(const osg::Vec3& center,float radius) 
     384{ 
     385 
     386    osg::Geode* geode  = new osg::Geode; 
     387 
     388//////////////////////////////////////////////////////////////////////////////////////////////////////// 
     389//     
     390// Examples of how to set up axis/orientation alignments 
     391// 
     392 
     393    float characterSize=radius*0.2f; 
     394     
     395    osg::Vec3 pos(center.x()-radius*.5f,center.y()-radius*.5f,center.z()-radius*.5f); 
     396 
     397    osgText::Text* text1 = new osgText::Text; 
     398    text1->setFont("fonts/times.ttf"); 
     399    text1->setCharacterSize(characterSize); 
     400    text1->setPosition(pos); 
     401    text1->setAxisAlignment(osgText::Text::XY_PLANE); 
     402    text1->setText("XY_PLANE"); 
     403    geode->addDrawable(text1); 
     404 
     405    osgText::Text* text2 = new osgText::Text; 
     406    text2->setFont("fonts/times.ttf"); 
     407    text2->setCharacterSize(characterSize); 
     408    text2->setPosition(pos); 
     409    text2->setAxisAlignment(osgText::Text::YZ_PLANE); 
     410    text2->setText("YZ_PLANE"); 
     411    geode->addDrawable(text2); 
     412 
     413    osgText::Text* text3 = new osgText::Text; 
     414    text3->setFont("fonts/times.ttf"); 
     415    text3->setCharacterSize(characterSize); 
     416    text3->setPosition(pos); 
     417    text3->setAxisAlignment(osgText::Text::XZ_PLANE); 
     418    text3->setText("XZ_PLANE"); 
     419    geode->addDrawable(text3); 
     420 
     421 
     422    osgText::Text* text4 = new osgText::Text; 
     423    text4->setFont("fonts/times.ttf"); 
     424    text4->setCharacterSize(characterSize); 
     425    text4->setPosition(center); 
     426    text4->setAxisAlignment(osgText::Text::SCREEN); 
     427 
     428    osg::Vec4 characterSizeModeColor(1.0f,0.0f,0.5f,1.0f); 
     429 
     430    osgText::Text* text5 = new osgText::Text; 
     431    text5->setColor(characterSizeModeColor); 
     432    text5->setFont("fonts/times.ttf"); 
     433    //text5->setCharacterSize(characterSize); 
     434    text5->setCharacterSize(32.0f); // medium 
     435    text5->setPosition(center - osg::Vec3(0.0, 0.0, 0.2)); 
     436    text5->setAxisAlignment(osgText::Text::SCREEN); 
     437    text5->setCharacterSizeMode(osgText::Text::SCREEN_COORDS); 
     438    text5->setText("CharacterSizeMode SCREEN_COORDS(size 32.0)"); 
     439    geode->addDrawable(text5); 
     440 
     441    osgText::Text* text6 = new osgText::Text; 
     442    text6->setColor(characterSizeModeColor); 
     443    text6->setFont("fonts/times.ttf"); 
     444    text6->setCharacterSize(characterSize); 
     445    text6->setPosition(center - osg::Vec3(0.0, 0.0, 0.4)); 
     446    text6->setAxisAlignment(osgText::Text::SCREEN); 
     447    text6->setCharacterSizeMode(osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT); 
     448    text6->setText("CharacterSizeMode OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT"); 
     449    geode->addDrawable(text6); 
     450 
     451    osgText::Text* text7 = new osgText::Text; 
     452    text7->setColor(characterSizeModeColor); 
     453    text7->setFont("fonts/times.ttf"); 
     454    text7->setCharacterSize(characterSize); 
     455    text7->setPosition(center - osg::Vec3(0.0, 0.0, 0.6)); 
     456    text7->setAxisAlignment(osgText::Text::SCREEN); 
     457    text7->setCharacterSizeMode(osgText::Text::OBJECT_COORDS); 
     458    text7->setText("CharacterSizeMode OBJECT_COORDS (default)"); 
     459    geode->addDrawable(text7); 
     460 
     461#if 1 
     462    // reproduce outline bounding box compute problem with backdrop on. 
     463    text4->setBackdropType(osgText::Text::OUTLINE); 
     464    text4->setDrawMode(osgText::Text::TEXT | osgText::Text::BOUNDINGBOX); 
     465#endif 
     466 
     467    text4->setText("SCREEN"); 
     468    geode->addDrawable(text4); 
     469 
     470    osg::ShapeDrawable* shape = new osg::ShapeDrawable(new osg::Sphere(center,characterSize*0.2f)); 
     471    shape->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::ON); 
     472    geode->addDrawable(shape); 
     473 
     474    osg::Group* rootNode = new osg::Group; 
     475    rootNode->addChild(geode); 
     476 
     477    return rootNode;     
     478} 
    43479 
    44480class UpdateTextOperation : public osg::Operation 
     
    46482public: 
    47483 
    48   UpdateTextOperation(osg::Group* group):         
    49       Operation("UpdateTextOperation", true), 
    50         _group(group), 
     484    UpdateTextOperation(const osg::Vec3& center, float diameter, osg::Group* group):         
     485        Operation("UpdateTextOperation", true), 
     486        _center(center), 
     487        _diameter(diameter), 
    51488        _maxNumChildren(200), 
    52         _maxNumTextPerGeode(10) 
    53       { 
    54       } 
    55  
    56       virtual void operator () (osg::Object* callingObject) 
    57       { 
     489        _maxNumTextPerGeode(10), 
     490        _group(group) 
     491    { 
     492    } 
     493 
     494    virtual void operator () (osg::Object* callingObject) 
     495    { 
    58496        // decided which method to call according to whole has called me. 
    59497        osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(callingObject); 
     
    61499        if (viewer) update(); 
    62500        else load(); 
    63       } 
    64  
    65       void update() 
    66       { 
     501    } 
     502     
     503    void update() 
     504    { 
    67505        // osg::notify(osg::NOTICE)<<"*** Doing update"<<std::endl; 
    68  
     506         
    69507        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
    70  
     508         
    71509        if (_mergeSubgraph.valid()) 
    72510        { 
    73           _group->addChild(_mergeSubgraph.get()); 
    74  
    75           _mergeSubgraph = 0; 
    76  
    77           if (_group->getNumChildren()>_maxNumChildren) 
    78           { 
    79             osg::Geode* geode = dynamic_cast<osg::Geode*>(_group->getChild(0)); 
    80             if (geode) 
     511            _group->addChild(_mergeSubgraph.get()); 
     512 
     513            _mergeSubgraph = 0; 
     514 
     515            if (_group->getNumChildren()>_maxNumChildren) 
    81516            { 
    82               _availableSubgraph.push_back(geode); 
    83               geode->removeDrawables(0,geode->getNumDrawables()); 
     517                osg::Geode* geode = dynamic_cast<osg::Geode*>(_group->getChild(0)); 
     518                if (geode) 
     519                { 
     520                    _availableSubgraph.push_back(geode); 
     521                    geode->removeDrawables(0,geode->getNumDrawables()); 
     522                } 
     523                _group->removeChild(0,1); 
    84524            } 
    85             _group->removeChild(0,1); 
    86           } 
    87  
    88           _waitOnMergeBlock.release(); 
     525             
     526            _waitOnMergeBlock.release(); 
    89527        }         
    90       } 
    91  
    92       void load() 
    93       { 
    94  
     528    } 
     529     
     530    void load() 
     531    { 
     532     
    95533        // osg::notify(osg::NOTICE)<<"Doing load"<<std::endl; 
    96534 
    97535        osg::ref_ptr<osg::Geode> geode; 
    98536        { 
    99           OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
    100           if (!_availableSubgraph.empty()) 
    101           { 
    102             geode = _availableSubgraph.front(); 
    103             _availableSubgraph.pop_front(); 
    104           } 
     537            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
     538            if (!_availableSubgraph.empty()) 
     539            { 
     540                geode = _availableSubgraph.front(); 
     541                _availableSubgraph.pop_front(); 
     542            } 
    105543        } 
    106  
     544         
    107545        if (!geode) geode = new osg::Geode; 
    108546 
    109547        for(unsigned int i=0; i<_maxNumTextPerGeode; ++i) 
    110548        { 
    111           osg::Vec3 position(float(rand()) / float(RAND_MAX), float(rand()) / float(RAND_MAX), float(i)/float(_maxNumTextPerGeode)); 
    112  
    113           std::string str; 
    114           unsigned int _numCharacters = 5; 
    115           for(unsigned int ni=0; ni<_numCharacters;++ni) 
    116           { 
    117             str.push_back(char(32.0 + (float(rand())/float(RAND_MAX))*128.0f)); 
    118           } 
    119  
    120           osgText::Text* text = new osgText::Text; 
    121           text->setDataVariance(osg::Object::DYNAMIC); 
    122           text->setPosition(position); 
    123           text->setFont("times.ttf"); 
    124           text->setText(str); 
    125           text->setCharacterSize(0.025f); 
    126           text->setAxisAlignment(osgText::Text::SCREEN); 
    127  
    128           geode->addDrawable(text); 
     549            float x = float(rand()) / float(RAND_MAX) - 0.5f; 
     550            float y = float(rand()) / float(RAND_MAX) - 0.5f; 
     551            float z = float(i)      / float(_maxNumTextPerGeode) - 0.5f; 
     552            osg::Vec3 position(x, y, z); 
     553 
     554            std::string str; 
     555            unsigned int _numCharacters = 5; 
     556            for(unsigned int ni=0; ni<_numCharacters;++ni) 
     557            { 
     558                str.push_back(char(32.0 + (float(rand())/float(RAND_MAX))*128.0f)); 
     559            } 
     560                         
     561            osgText::Text* text = new osgText::Text; 
     562            text->setDataVariance(osg::Object::DYNAMIC); 
     563            text->setPosition(_center + position * _diameter); 
     564            text->setFont("times.ttf"); 
     565            text->setText(str); 
     566            text->setCharacterSize(0.025f * _diameter); 
     567            text->setAxisAlignment(osgText::Text::SCREEN); 
     568             
     569            geode->addDrawable(text); 
    129570        } 
    130571 
    131572 
    132573        {         
    133           OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
    134           _mergeSubgraph = geode; 
     574            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
     575            _mergeSubgraph = geode; 
    135576        } 
    136  
     577         
    137578        // osg::notify(osg::NOTICE)<<"Waiting on merge"<<std::endl; 
    138579 
    139580        _waitOnMergeBlock.block(); 
    140581 
    141       } 
    142  
    143       virtual void release() 
    144       { 
     582    } 
     583     
     584    virtual void release() 
     585    { 
    145586        _waitOnMergeBlock.release(); 
    146       } 
    147  
    148       typedef std::list< osg::ref_ptr<osg::Geode> > AvailableList; 
    149  
    150       unsigned int                _maxNumChildren; 
    151       unsigned int                _maxNumTextPerGeode; 
    152  
    153       OpenThreads::Mutex          _mutex; 
    154       osg::ref_ptr<osg::Group>    _group; 
    155       osg::ref_ptr<osg::Geode>    _mergeSubgraph; 
    156       AvailableList               _availableSubgraph; 
    157       OpenThreads::Block          _waitOnMergeBlock; 
    158  
    159       unsigned int                _counter; 
     587    } 
     588 
     589    typedef std::list< osg::ref_ptr<osg::Geode> > AvailableList; 
     590 
     591    osg::Vec3                   _center; 
     592    float                       _diameter; 
     593    unsigned int                _maxNumChildren; 
     594    unsigned int                _maxNumTextPerGeode; 
     595     
     596    OpenThreads::Mutex          _mutex; 
     597    osg::ref_ptr<osg::Group>    _group; 
     598    osg::ref_ptr<osg::Geode>    _mergeSubgraph; 
     599    AvailableList               _availableSubgraph; 
     600    OpenThreads::Block          _waitOnMergeBlock; 
     601     
     602    unsigned int                _counter; 
    160603 
    161604}; 
     
    164607int main(int argc, char** argv) 
    165608{ 
    166   osg::ArgumentParser arguments(&argc, argv); 
    167  
    168  
    169   osg::Referenced::setThreadSafeReferenceCounting(true); 
    170  
    171   // construct the viewer. 
    172   osgViewer::Viewer viewer(arguments); 
    173  
    174   typedef std::list< osg::ref_ptr<osg::OperationThread> > Threads; 
    175  
    176   Threads operationThreads; 
    177   osg::ref_ptr<UpdateTextOperation> updateOperation; 
    178  
    179   unsigned int numThreads = 0; 
    180   if (arguments.read("--mt", numThreads) || arguments.read("--mt")) 
    181   { 
    182     // construct a multi-threaded text updating test. 
    183     if (numThreads==0) numThreads = 1; 
    184  
    185     // create a group to add everything into. 
    186     osg::Group* mainGroup = new osg::Group; 
    187  
    188     osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments); 
    189     mainGroup->addChild(loadedModel.get()); 
    190  
    191     for(unsigned int i=0; i<numThreads; ++i) 
    192     { 
    193       osg::Group* textGroup = new osg::Group; 
    194       mainGroup->addChild(textGroup); 
    195  
    196       // create the background thread 
    197       osg::OperationThread* operationThread = new osg::OperationThread; 
    198  
    199       operationThreads.push_back(operationThread); 
    200  
    201       // create the operation that will run in the background and 
    202       // sync once per frame with the main viewer loop. 
    203       updateOperation = new UpdateTextOperation(textGroup); 
    204  
    205       // add the operation to the operation thread and start it. 
    206       operationThread->add(updateOperation.get()); 
    207       operationThread->startThread(); 
    208  
    209       // add the operation to the viewer to sync once per frame. 
    210       viewer.addUpdateOperation(updateOperation.get()); 
    211  
    212  
    213       // add a unit cube for the text to appear within. 
    214       osg::Geode* geode = new osg::Geode; 
    215       geode->getOrCreateStateSet()->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE)); 
    216       geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.5f,0.5f,0.5f),1.0))); 
    217  
    218       mainGroup->addChild(geode); 
    219     } 
    220  
    221     viewer.setSceneData(mainGroup);         
    222   } 
    223    
     609    osg::ArgumentParser arguments(&argc, argv); 
     610 
     611    // construct the viewer. 
     612    osgViewer::Viewer viewer(arguments); 
     613     
     614    typedef std::list< osg::ref_ptr<osg::OperationThread> > Threads; 
     615 
     616    Threads operationThreads; 
     617    osg::ref_ptr<UpdateTextOperation> updateOperation; 
     618 
     619    unsigned int numThreads = 0; 
     620    if (arguments.read("--mt", numThreads) || arguments.read("--mt")) 
     621    { 
     622        // construct a multi-threaded text updating test. 
     623        if (numThreads==0) numThreads = 1; 
     624         
     625        // create a group to add everything into. 
     626        osg::Group* mainGroup = new osg::Group; 
     627         
     628        osg::Vec3 center(0.5f,0.5f,0.5f); 
     629        float diameter = 1.0f; 
     630         
     631        osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments); 
     632        if (loadedModel.valid()) 
     633        { 
     634            mainGroup->addChild(loadedModel.get()); 
     635             
     636            center = loadedModel->getBound().center(); 
     637            diameter = loadedModel->getBound().radius() * 2.0f; 
     638        } 
     639         
     640        for(unsigned int i=0; i<numThreads; ++i) 
     641        { 
     642            osg::Group* textGroup = new osg::Group; 
     643            mainGroup->addChild(textGroup); 
     644 
     645            // create the background thread 
     646            osg::OperationThread* operationThread = new osg::OperationThread; 
     647             
     648            operationThreads.push_back(operationThread); 
     649 
     650            // create the operation that will run in the background and 
     651            // sync once per frame with the main viewer loop. 
     652            updateOperation = new UpdateTextOperation(center, diameter, textGroup); 
     653 
     654            // add the operation to the operation thread and start it. 
     655            operationThread->add(updateOperation.get()); 
     656            operationThread->startThread(); 
     657 
     658            // add the operation to the viewer to sync once per frame. 
     659            viewer.addUpdateOperation(updateOperation.get()); 
     660 
     661 
     662            // add a unit cube for the text to appear within. 
     663            osg::Geode* geode = new osg::Geode; 
     664            geode->getOrCreateStateSet()->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE)); 
     665            geode->addDrawable(new osg::ShapeDrawable(new osg::Box(center,diameter))); 
     666 
     667            mainGroup->addChild(geode); 
     668        } 
     669                 
     670        viewer.setSceneData(mainGroup);         
     671    } 
     672    else 
     673    { 
     674        // prepare scene. 
     675        osg::Vec3 center(0.0f,0.0f,0.0f); 
     676        float radius = 1.0f; 
     677         
     678        // make sure the root node is group so we can add extra nodes to it. 
     679        osg::Group* group = new osg::Group; 
     680         
     681        { 
     682            // create the hud. 
     683            osg::Camera* camera = new osg::Camera; 
     684            camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); 
     685            camera->setProjectionMatrixAsOrtho2D(0,1280,0,1024); 
     686            camera->setViewMatrix(osg::Matrix::identity()); 
     687            camera->setClearMask(GL_DEPTH_BUFFER_BIT); 
     688            camera->addChild(createHUDText()); 
     689            camera->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF); 
     690 
     691            group->addChild(camera); 
     692        } 
     693 
     694        group->addChild(create3DText(center,radius)); 
     695 
     696        // set the scene to render 
     697        viewer.setSceneData(group); 
     698    } 
    224699 
    225700#if 0 
    226   osgDB::writeNodeFile(*viewer.getSceneData(),"text.osg"); 
     701    osgDB::writeNodeFile(*viewer.getSceneData(),"text.osg"); 
    227702#endif 
    228703 
    229   viewer.addEventHandler(new osgViewer::StatsHandler()); 
    230   viewer.addEventHandler( new osgViewer::ThreadingHandler ); 
    231   viewer.addEventHandler( new osgViewer::WindowSizeHandler ); 
    232  
    233  
    234   viewer.run(); 
    235  
    236   if (!operationThreads.empty()) 
    237   { 
    238     for(Threads::iterator itr = operationThreads.begin(); 
    239       itr != operationThreads.begin(); 
    240       ++itr) 
    241     { 
    242       (*itr)->cancel(); 
    243     } 
    244   } 
    245  
    246   return 0; 
     704    viewer.addEventHandler(new osgViewer::StatsHandler()); 
     705 
     706    viewer.run(); 
     707     
     708    if (!operationThreads.empty()) 
     709    { 
     710        for(Threads::iterator itr = operationThreads.begin(); 
     711            itr != operationThreads.end(); 
     712            ++itr) 
     713        { 
     714            (*itr)->cancel(); 
     715        } 
     716    } 
    247717} 
    248718