From 8e6a1d38e4755b9f2640cba6a99d3510d4d45849 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 5 Mar 2003 12:28:42 +0000 Subject: [PATCH] Updates to the GLUT and Producer text demo. Fix to text to better handle unsetting of vertex arrays. --- examples/osgtext/osgtext.cpp | 208 ++++++++-- src/Demos/osgtext/main.cpp | 764 ++++++++++++++++++++--------------- src/osgText/Font.cpp | 1 + src/osgText/Text.cpp | 2 + 4 files changed, 627 insertions(+), 348 deletions(-) diff --git a/examples/osgtext/osgtext.cpp b/examples/osgtext/osgtext.cpp index 3742e6dc1..837809b96 100644 --- a/examples/osgtext/osgtext.cpp +++ b/examples/osgtext/osgtext.cpp @@ -43,6 +43,11 @@ osg::Group* createHUDText() float margin = 50.0f; +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Examples of how to set up different text layout +// + osg::Vec4 layoutColor(1.0f,1.0f,0.0f,1.0f); float layoutCharacterSize = 20.0f; @@ -90,6 +95,11 @@ osg::Group* createHUDText() } +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Examples of how to set up different font resolution +// + osg::Vec4 fontSizeColor(0.0f,1.0f,1.0f,1.0f); float fontSizeCharacterSize = 30; @@ -140,6 +150,11 @@ osg::Group* createHUDText() } +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Examples of how to set up different sized text +// + osg::Vec4 characterSizeColor(1.0f,0.0f,1.0f,1.0f); cursor.y() -= fontSizeCharacterSize*2.0f; @@ -189,82 +204,215 @@ osg::Group* createHUDText() } - cursor.x() = 500; - cursor.y() = margin; +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Examples of how to set up different alignments +// + + osg::Vec4 alignmentSizeColor(0.0f,1.0f,0.0f,1.0f); + float alignmentCharacterSize = 25.0f; + cursor.x() = 640; + cursor.y() = margin*4.0f; + + typedef std::pair AlignmentPair; + typedef std::vector AlignmentList; + AlignmentList alignmentList; + alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_TOP,"text->setAlignment(osgText::Text::LEFT_TOP);")); + alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_CENTER,"text->setAlignment(osgText::Text::LEFT_CENTER);")); + alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_BOTTOM,"text->setAlignment(osgText::Text::LEFT_BOTTOM);")); + alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_TOP,"text->setAlignment(osgText::Text::CENTER_TOP);")); + alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_CENTER,"text->setAlignment(osgText::Text::CENTER_CENTER);")); + alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_BOTTOM,"text->setAlignment(osgText::Text::CENTER_BOTTOM);")); + alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_TOP,"text->setAlignment(osgText::Text::RIGHT_TOP);")); + alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_CENTER,"text->setAlignment(osgText::Text::RIGHT_CENTER);")); + alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_BOTTOM,"text->setAlignment(osgText::Text::RIGHT_BOTTOM);")); + alignmentList.push_back(AlignmentPair(osgText::Text::BASE_LINE,"text->setAlignment(osgText::Text::BASE_LINE);//default")); osg::Sequence* sequence = new osg::Sequence; - - sequence->setMode(osg::Sequence::START); - sequence->setInterval(osg::Sequence::LOOP, 0, -1); - sequence->setDuration(1.0f, -1); - -// osg::Group* sequence = new osg::Group; -// rootNode->addChild(sequence); - { - for(unsigned int i=osgText::Text::LEFT_TOP;i<=osgText::Text::BASE_LINE;i++) + for(AlignmentList::iterator itr=alignmentList.begin(); + itr!=alignmentList.end(); + ++itr) { osg::Geode* alignmentGeode = new osg::Geode; sequence->addChild(alignmentGeode); - sequence->setTime(i, 1.0f); + sequence->setTime(sequence->getNumChildren(), 1.0f); osgText::Text* text = new osgText::Text; text->setFont(font); - text->setColor(characterSizeColor); + text->setColor(alignmentSizeColor); + text->setCharacterSize(alignmentCharacterSize); text->setPosition(cursor); text->setDrawMode(osgText::Text::TEXT|osgText::Text::ALIGNMENT|osgText::Text::BOUNDINGBOX); - text->setAlignment((osgText::Text::AlignmentType)i); + text->setAlignment(itr->first); + text->setText(itr->second); - text->setText("text->setAlignment();"); alignmentGeode->addDrawable(text); - cursor.y() += 40.0f; - } } + + sequence->setMode(osg::Sequence::START); + sequence->setInterval(osg::Sequence::LOOP, 0, -1); + sequence->setDuration(1.0f, -1); + rootNode->addChild(sequence); + + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Examples of how to set up different fonts... +// + + cursor.x() = margin*2.0f; + cursor.y() = margin*2.0f; + + osg::Vec4 fontColor(1.0f,0.5f,0.0f,1.0f); + float fontCharacterSize = 20.0f; + float spacing = 40.0f; + + { + osgText::Text* text = new osgText::Text; + text->setColor(fontColor); + text->setPosition(cursor); + text->setCharacterSize(fontCharacterSize); + + text->setFont(0); + text->setText("text->setFont(0); // inbuilt font."); + geode->addDrawable(text); + + cursor.x() = text->getBound().xMax() + spacing ; + } + + { + osgText::Font* arial = osgText::readFontFile("fonts/arial.ttf"); + + osgText::Text* text = new osgText::Text; + text->setColor(fontColor); + text->setPosition(cursor); + text->setCharacterSize(fontCharacterSize); + + text->setFont(arial); + text->setText(arial!=0? + "text->setFont(\"fonts/arial.ttf\");": + "unable to load \"fonts/arial.ttf\""); + geode->addDrawable(text); + + cursor.x() = text->getBound().xMax() + spacing ; + } + + { + osgText::Font* times = osgText::readFontFile("fonts/times.ttf"); + + osgText::Text* text = new osgText::Text; + text->setColor(fontColor); + text->setPosition(cursor); + text->setCharacterSize(fontCharacterSize); + + geode->addDrawable(text); + text->setFont(times); + text->setText(times!=0? + "text->setFont(\"fonts/times.ttf\");": + "unable to load \"fonts/times.ttf\""); + + cursor.x() = text->getBound().xMax() + spacing ; + } + + cursor.x() = margin*2.0f; + cursor.y() = margin; + + { + osgText::Font* dirtydoz = osgText::readFontFile("fonts/dirtydoz.ttf"); + + osgText::Text* text = new osgText::Text; + text->setColor(fontColor); + text->setPosition(cursor); + text->setCharacterSize(fontCharacterSize); + + text->setFont(dirtydoz); + text->setText(dirtydoz!=0? + "text->setFont(\"fonts/dirtydoz.ttf\");": + "unable to load \"fonts/dirtydoz.ttf\""); + geode->addDrawable(text); + + cursor.x() = text->getBound().xMax() + spacing ; + } + + { + osgText::Font* fudd = osgText::readFontFile("fonts/fudd.ttf"); + + osgText::Text* text = new osgText::Text; + text->setColor(fontColor); + text->setPosition(cursor); + text->setCharacterSize(fontCharacterSize); + + text->setFont(fudd); + text->setText(fudd!=0? + "text->setFont(\"fonts/fudd.ttf\");": + "unable to load \"fonts/fudd.ttf\""); + geode->addDrawable(text); + + cursor.x() = text->getBound().xMax() + spacing ; + } return rootNode; } -osg::Group* create3DText() + + + +// create text which sits in 3D space such as would be inserted into a normal model +osg::Group* create3DText(const osg::Vec3& center,float radius) { osg::Geode* geode = new osg::Geode; +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Examples of how to set up axis/orientation alignments +// + + float characterSize=radius*0.2f; + + osg::Vec3 pos(center.x()-radius*.5f,center.y()-radius*.5f,center.z()-radius*.5f); + osgText::Text* text1 = new osgText::Text; text1->setFont("fonts/times.ttf"); + text1->setCharacterSize(characterSize); + text1->setPosition(pos); text1->setAxisAlignment(osgText::Text::XY_PLANE); text1->setText("XY_PLANE"); geode->addDrawable(text1); osgText::Text* text2 = new osgText::Text; text2->setFont("fonts/times.ttf"); - text2->setPosition(osg::Vec3(0.0f,0.0f,0.0f)); + text2->setCharacterSize(characterSize); + text2->setPosition(pos); text2->setAxisAlignment(osgText::Text::YZ_PLANE); text2->setText("YZ_PLANE"); geode->addDrawable(text2); osgText::Text* text3 = new osgText::Text; text3->setFont("fonts/times.ttf"); - text3->setPosition(osg::Vec3(00.0f,00.0f,00.0f)); + text3->setCharacterSize(characterSize); + text3->setPosition(pos); text3->setAxisAlignment(osgText::Text::XZ_PLANE); text3->setText("XZ_PLANE"); geode->addDrawable(text3); - osg::Vec3 screenCenter(300.0f,00.0f,00.0f); osgText::Text* text4 = new osgText::Text; text4->setFont("fonts/times.ttf"); + text4->setCharacterSize(characterSize); + text4->setPosition(center); text4->setAxisAlignment(osgText::Text::SCREEN); - text4->setPosition(screenCenter); text4->setText("SCREEN"); geode->addDrawable(text4); - osg::ShapeDrawable* shape = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(screenCenter),2.0f)); + osg::ShapeDrawable* shape = new osg::ShapeDrawable(new osg::Sphere(center,characterSize*0.2f)); shape->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::ON); geode->addDrawable(shape); @@ -318,11 +466,18 @@ int main( int argc, char **argv ) // prepare scene. { + osg::Vec3 center(0.0f,0.0f,0.0f); + float radius = 1.0f; + if (rootNode.valid()) { // optimize the scene graph, remove rendundent nodes and state etc. osgUtil::Optimizer optimizer; optimizer.optimize(rootNode.get()); + + const osg::BoundingSphere& bs = rootNode->getBound(); + center = bs.center(); + radius = bs.radius(); } // make sure the root node is group so we can add extra nodes to it. @@ -352,17 +507,12 @@ int main( int argc, char **argv ) group->addChild(projection); } - osg::MatrixTransform* scale = new osg::MatrixTransform; - scale->setMatrix(osg::Matrix::scale(1.0f,1.0f,1.0f)); - scale->addChild(create3DText()); - group->addChild(scale); + group->addChild(create3DText(center,radius)); } // set the scene to render viewer.setSceneData(rootNode.get()); - - osgDB::writeNodeFile(*rootNode,"test.osg"); // create the windows and run the threads. viewer.realize(Producer::CameraGroup::ThreadPerCamera); diff --git a/src/Demos/osgtext/main.cpp b/src/Demos/osgtext/main.cpp index c8687edaf..0e61638a8 100644 --- a/src/Demos/osgtext/main.cpp +++ b/src/Demos/osgtext/main.cpp @@ -1,382 +1,508 @@ -/* -------------------------------------------------------------------------- - * - * osgText demo - * - * -------------------------------------------------------------------------- - * - * prog: max rheiner;mrn@paus.ch - * date: 4/26/2001 (m/d/y) - * - * -------------------------------------------------------------------------- - */ - -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include #include #include #include -#include -#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include #include -#include -using namespace osgGLUT; - -/////////////////////////////////////////////////////////////////////////////// -// globals -#define TEXT_POLYGON "Polygon Font - jygq" -#define TEXT_OUTLINE "Outline Font - jygq" -#define TEXT_TEXTURE "Texture Font - jygq" -#define TEXT_BITMAP "Bitmap Font - jygq" -#define TEXT_PIXMAP "Pixmap Font - jygq" - -#define TEXT_COL_2D osg::Vec4(.9,.9,.9,1) -#define TEXT_COL_3D osg::Vec4(.99,.3,.2,1) - - -std::string timesFont("fonts/times.ttf"); -std::string arialFont("fonts/arial.ttf"); - -int gFontSize=18; -int gFontSize1=24; -std::vector gTextList; -osgText::Text::AlignmentType gAlignment=osgText::Text::BASE_LINE; - - -void set2dScene(osg::Group* rootNode) +osg::Group* createHUDText() { - osg::Geode* geode = new osg::Geode(); + + osg::Group* rootNode = new osg::Group; + + osgText::Font* font = osgText::readFontFile("fonts/arial.ttf"); + + osg::Geode* geode = new osg::Geode; rootNode->addChild(geode); + + float windowHeight = 1024.0f; + float windowWidth = 1280.0f; + float margin = 50.0f; + + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Examples of how to set up different text layout +// + + osg::Vec4 layoutColor(1.0f,1.0f,0.0f,1.0f); + float layoutCharacterSize = 20.0f; - osg::Vec3 position(150.0f,10.0f,0.0f); - osg::Vec3 delta(90.0f,120.0f,0.0f); + { + osgText::Text* text = new osgText::Text; + text->setFont(font); + text->setColor(layoutColor); + text->setCharacterSize(layoutCharacterSize); + text->setPosition(osg::Vec3(margin,windowHeight-margin,0.0f)); + + // the default layout is left to right, typically used in languages + // originating from europe such as English, French, German, Spanish etc.. + text->setLayout(osgText::Text::LEFT_TO_RIGHT); + + text->setText("text->setLayout(osgText::Text::LEFT_TO_RIGHT);"); + geode->addDrawable(text); + } { - osgText::Text* text = new osgText::Text; - geode->addDrawable( text ); - gTextList.push_back(text); + osgText::Text* text = new osgText::Text; + text->setFont(font); + text->setColor(layoutColor); + text->setCharacterSize(layoutCharacterSize); + text->setPosition(osg::Vec3(windowWidth-margin,windowHeight-margin,0.0f)); - text->setFont(timesFont); - text->setFontSize(gFontSize,gFontSize); - text->setText("String 1"); - text->setPosition(position); - text->setDrawMode( osgText::Text::TEXT | - osgText::Text::BOUNDINGBOX | - osgText::Text::ALIGNMENT ); - text->setAlignment(gAlignment); - - position += delta; - } + // right to left layouts would be used for hebrew or arabic fonts. + text->setLayout(osgText::Text::RIGHT_TO_LEFT); + text->setText("text->setLayout(osgText::Text::RIGHT_TO_LEFT);"); + geode->addDrawable(text); + } { - osgText::Text* text = new osgText::Text; - geode->addDrawable( text ); - gTextList.push_back(text); + osgText::Text* text = new osgText::Text; + text->setFont(font); + text->setColor(layoutColor); + text->setPosition(osg::Vec3(margin,windowHeight-margin,0.0f)); + text->setCharacterSize(layoutCharacterSize); - text->setFont(timesFont); - text->setFontSize(gFontSize,gFontSize); - text->setText("String 1"); - text->setPosition(position); - text->setDrawMode( osgText::Text::TEXT | - osgText::Text::BOUNDINGBOX | - osgText::Text::ALIGNMENT ); - text->setAlignment(gAlignment); - - position += delta; - } + // vertical font layout would be used for asian fonts. + text->setLayout(osgText::Text::VERTICAL); - - { - osgText::Text* text = new osgText::Text; - geode->addDrawable( text ); - gTextList.push_back(text); - - text->setFont(timesFont); - text->setFontSize(gFontSize,gFontSize); - text->setText("String 1"); - text->setPosition(position); - text->setDrawMode( osgText::Text::TEXT | - osgText::Text::BOUNDINGBOX | - osgText::Text::ALIGNMENT ); - text->setAlignment(gAlignment); - - position += delta; - } -} - -void setScene(osg::Group* rootNode) -{ - osg::Geode* geode = new osg::Geode(); - rootNode->addChild(geode); + text->setText("text->setLayout(osgText::Text::VERTICAL);"); + geode->addDrawable(text); + } - osg::Vec3 position(150.0f,10.0f,0.0f); - osg::Vec3 delta(90.0f,120.0f,0.0f); + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Examples of how to set up different font resolution +// + osg::Vec4 fontSizeColor(0.0f,1.0f,1.0f,1.0f); + float fontSizeCharacterSize = 30; + + osg::Vec3 cursor = osg::Vec3(margin*2,windowHeight-margin*2,0.0f); + { - osgText::Text* text = new osgText::Text; - geode->addDrawable( text ); - gTextList.push_back(text); - - text->setFont(timesFont); - text->setFontSize(gFontSize,gFontSize); - text->setText("String 1"); - text->setPosition(position); - text->setDrawMode( osgText::Text::TEXT | - osgText::Text::BOUNDINGBOX | - osgText::Text::ALIGNMENT ); - text->setAlignment(gAlignment); + osgText::Text* text = new osgText::Text; + text->setFont(font); + text->setColor(fontSizeColor); + text->setCharacterSize(fontSizeCharacterSize); + text->setPosition(cursor); - position += delta; - } - - - { - osgText::Text* text = new osgText::Text; - geode->addDrawable( text ); - gTextList.push_back(text); - - text->setFont(timesFont); - text->setFontSize(gFontSize,gFontSize); - text->setText("String 1"); - text->setPosition(position); - text->setDrawMode( osgText::Text::TEXT | - osgText::Text::BOUNDINGBOX | - osgText::Text::ALIGNMENT ); - text->setAlignment(gAlignment); + // use text that uses 10 by 10 texels as a target resolution for fonts. + text->setFontSize(10,10); // blocky but small texture memory usage - position += delta; - } - - + text->setText("text->setFontSize(10,10); // blocky but small texture memory usage"); + geode->addDrawable(text); + } + + cursor.y() -= fontSizeCharacterSize; { - osgText::Text* text = new osgText::Text; - geode->addDrawable( text ); - gTextList.push_back(text); - - text->setFont(timesFont); - text->setFontSize(gFontSize,gFontSize); - text->setText("String 1"); - text->setPosition(position); - text->setDrawMode( osgText::Text::TEXT | - osgText::Text::BOUNDINGBOX | - osgText::Text::ALIGNMENT ); - text->setAlignment(gAlignment); + osgText::Text* text = new osgText::Text; + text->setFont(font); + text->setColor(fontSizeColor); + text->setCharacterSize(fontSizeCharacterSize); + text->setPosition(cursor); - position += delta; - } - -} - -class TextViewer: public osgGLUT::Viewer -{ -public: - - virtual float update(unsigned int viewport) + // use text that uses 10 by 10 texels as a target resolution for fonts. + text->setFontSize(20,20); // smoother but higher texture memory usage (but still quite low). + + text->setText("text->setFontSize(20,20); // smoother but higher texture memory usage (but still quite low)."); + geode->addDrawable(text); + } + + cursor.y() -= fontSizeCharacterSize; { - float ret; - ret=Viewer::update(viewport); - if(_hudSceneView.valid() && viewport>=_viewportList.size()-1) + osgText::Text* text = new osgText::Text; + text->setFont(font); + text->setColor(fontSizeColor); + text->setCharacterSize(fontSizeCharacterSize); + text->setPosition(cursor); + + // use text that uses 10 by 10 texels as a target resolution for fonts. + text->setFontSize(40,40); // even smoother but again higher texture memory usage. + + text->setText("text->setFontSize(40,40); // even smoother but again higher texture memory usage."); + geode->addDrawable(text); + } + + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Examples of how to set up different sized text +// + + osg::Vec4 characterSizeColor(1.0f,0.0f,1.0f,1.0f); + + cursor.y() -= fontSizeCharacterSize*2.0f; + + { + osgText::Text* text = new osgText::Text; + text->setFont(font); + text->setColor(characterSizeColor); + text->setFontSize(20,20); + text->setPosition(cursor); + + // use text that 20 units high. + text->setCharacterSize(20); // small + + text->setText("text->setCharacterSize(15.0f); // small"); + geode->addDrawable(text); + } + + cursor.y() -= 30.0f; + { + osgText::Text* text = new osgText::Text; + text->setFont(font); + text->setColor(characterSizeColor); + text->setFontSize(30,30); + text->setPosition(cursor); + + // use text that 20 units high. + text->setCharacterSize(30.0f); // medium + + text->setText("text->setCharacterSize(30.0f); // medium"); + geode->addDrawable(text); + } + + cursor.y() -= 50.0f; + { + osgText::Text* text = new osgText::Text; + text->setFont(font); + text->setColor(characterSizeColor); + text->setFontSize(40,40); + text->setPosition(cursor); + + // use text that uses 10 by 10 texels as a target resolution for fonts. + text->setCharacterSize(60.0f); // large + + text->setText("text->setCharacterSize(60.0f); // large"); + geode->addDrawable(text); + } + + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Examples of how to set up different alignments +// + + osg::Vec4 alignmentSizeColor(0.0f,1.0f,0.0f,1.0f); + float alignmentCharacterSize = 25.0f; + cursor.x() = 640; + cursor.y() = margin*4.0f; + + typedef std::pair AlignmentPair; + typedef std::vector AlignmentList; + AlignmentList alignmentList; + alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_TOP,"text->setAlignment(osgText::Text::LEFT_TOP);")); + alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_CENTER,"text->setAlignment(osgText::Text::LEFT_CENTER);")); + alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_BOTTOM,"text->setAlignment(osgText::Text::LEFT_BOTTOM);")); + alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_TOP,"text->setAlignment(osgText::Text::CENTER_TOP);")); + alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_CENTER,"text->setAlignment(osgText::Text::CENTER_CENTER);")); + alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_BOTTOM,"text->setAlignment(osgText::Text::CENTER_BOTTOM);")); + alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_TOP,"text->setAlignment(osgText::Text::RIGHT_TOP);")); + alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_CENTER,"text->setAlignment(osgText::Text::RIGHT_CENTER);")); + alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_BOTTOM,"text->setAlignment(osgText::Text::RIGHT_BOTTOM);")); + alignmentList.push_back(AlignmentPair(osgText::Text::BASE_LINE,"text->setAlignment(osgText::Text::BASE_LINE);//default")); + + osg::Sequence* sequence = new osg::Sequence; + { + for(AlignmentList::iterator itr=alignmentList.begin(); + itr!=alignmentList.end(); + ++itr) { - _hudSceneView->update(); - } - return ret; - } - - virtual float cull(unsigned int viewport) - { - float ret; - ret=Viewer::cull(viewport); - if(_hudSceneView.valid() && viewport>=_viewportList.size()-1) - _hudSceneView->cull(); - return ret; - } + osg::Geode* alignmentGeode = new osg::Geode; + sequence->addChild(alignmentGeode); + sequence->setTime(sequence->getNumChildren(), 1.0f); - virtual float draw(unsigned int viewport) - { - float ret; - ret=Viewer::draw(viewport); - if(_hudSceneView.valid() && viewport>=_viewportList.size()-1) - _hudSceneView->draw(); - return ret; - } - - void addHUD(osg::Node* rootnode) - { - _hudSceneView = new osgUtil::SceneView; - _hudSceneView->setDefaults(); - _hudSceneView->setSceneData(rootnode); - - } - - virtual void reshape(GLint w, GLint h) - { - Viewer::reshape(w,h); - - if(_hudSceneView.valid()) - { - _hudSceneView->setViewport(0,0,w,h); - _hudCam->setOrtho2D(0,w,0,h); - } - } - - virtual bool open() - { - bool ret=Viewer::open(); - - // set the clear flag / after the visualReq.Visitor - if(_hudSceneView.valid()) - { - _hudSceneView->getRenderStage()->setClearMask(0); - _hudSceneView->getCullVisitor()->setCullingMode(osgUtil::CullVisitor::NO_CULLING); - _hudSceneView->setComputeNearFarMode(osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR); + osgText::Text* text = new osgText::Text; + text->setFont(font); + text->setColor(alignmentSizeColor); + text->setCharacterSize(alignmentCharacterSize); + text->setPosition(cursor); + text->setDrawMode(osgText::Text::TEXT|osgText::Text::ALIGNMENT|osgText::Text::BOUNDINGBOX); - _hudCam = new osg::Camera; + text->setAlignment(itr->first); + text->setText(itr->second); + + alignmentGeode->addDrawable(text); + - // leftBottom - _hudSceneView->setCamera(_hudCam.get()); } - - return ret; + } + sequence->setMode(osg::Sequence::START); + sequence->setInterval(osg::Sequence::LOOP, 0, -1); + sequence->setDuration(1.0f, -1); + + rootNode->addChild(sequence); -protected: - osg::ref_ptr _hudCam; - osg::ref_ptr _hudSceneView; +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Examples of how to set up different fonts... +// - virtual void clear() + cursor.x() = margin*2.0f; + cursor.y() = margin*2.0f; + + osg::Vec4 fontColor(1.0f,0.5f,0.0f,1.0f); + float fontCharacterSize = 20.0f; + float spacing = 40.0f; + { - Viewer::clear(); - _hudCam = NULL; - _hudSceneView = NULL; + osgText::Text* text = new osgText::Text; + text->setColor(fontColor); + text->setPosition(cursor); + text->setCharacterSize(fontCharacterSize); + + text->setFont(0); + text->setText("text->setFont(0); // inbuilt font."); + geode->addDrawable(text); + + cursor.x() = text->getBound().xMax() + spacing ; } - - - virtual void keyboard(int key, int x, int y, bool keydown) + { - if (keydown) - { - switch(key) - { - case '1': - { // change DrawMode - std::vector::iterator itr=gTextList.begin(); - for(;itr!=gTextList.end();itr++) - (*itr)->setDrawMode(osgText::Text::TEXT ^ (*itr)->getDrawMode()); - } - return; - case '2': - { // change DrawMode - std::vector::iterator itr=gTextList.begin(); - for(;itr!=gTextList.end();itr++) - (*itr)->setDrawMode(osgText::Text::BOUNDINGBOX ^ (*itr)->getDrawMode()); - } - return; - case '3': - { // change DrawMode - std::vector::iterator itr=gTextList.begin(); - for(;itr!=gTextList.end();itr++) - (*itr)->setDrawMode(osgText::Text::ALIGNMENT ^ (*itr)->getDrawMode()); - } - return; - /////////////////////////////////////////////////////////////////// - case '4': - { // change the textAlignment - gAlignment=(osgText::Text::AlignmentType)((int)gAlignment+1); - if(gAlignment>osgText::Text::BASE_LINE) - gAlignment=osgText::Text::LEFT_TOP; + osgText::Font* arial = osgText::readFontFile("fonts/arial.ttf"); - std::vector::iterator itr=gTextList.begin(); - for(;itr!=gTextList.end();itr++) - (*itr)->setAlignment(gAlignment); - } - return; - default: - break; - } - } - Viewer::keyboard(key,x,y,keydown); + osgText::Text* text = new osgText::Text; + text->setColor(fontColor); + text->setPosition(cursor); + text->setCharacterSize(fontCharacterSize); + + text->setFont(arial); + text->setText(arial!=0? + "text->setFont(\"fonts/arial.ttf\");": + "unable to load \"fonts/arial.ttf\""); + geode->addDrawable(text); + + cursor.x() = text->getBound().xMax() + spacing ; } + + { + osgText::Font* times = osgText::readFontFile("fonts/times.ttf"); -}; + osgText::Text* text = new osgText::Text; + text->setColor(fontColor); + text->setPosition(cursor); + text->setCharacterSize(fontCharacterSize); + + geode->addDrawable(text); + text->setFont(times); + text->setText(times!=0? + "text->setFont(\"fonts/times.ttf\");": + "unable to load \"fonts/times.ttf\""); + + cursor.x() = text->getBound().xMax() + spacing ; + } + + cursor.x() = margin*2.0f; + cursor.y() = margin; + + { + osgText::Font* dirtydoz = osgText::readFontFile("fonts/dirtydoz.ttf"); + + osgText::Text* text = new osgText::Text; + text->setColor(fontColor); + text->setPosition(cursor); + text->setCharacterSize(fontCharacterSize); + + text->setFont(dirtydoz); + text->setText(dirtydoz!=0? + "text->setFont(\"fonts/dirtydoz.ttf\");": + "unable to load \"fonts/dirtydoz.ttf\""); + geode->addDrawable(text); + + cursor.x() = text->getBound().xMax() + spacing ; + } + + { + osgText::Font* fudd = osgText::readFontFile("fonts/fudd.ttf"); + + osgText::Text* text = new osgText::Text; + text->setColor(fontColor); + text->setPosition(cursor); + text->setCharacterSize(fontCharacterSize); + + text->setFont(fudd); + text->setText(fudd!=0? + "text->setFont(\"fonts/fudd.ttf\");": + "unable to load \"fonts/fudd.ttf\""); + geode->addDrawable(text); + + cursor.x() = text->getBound().xMax() + spacing ; + } + + return rootNode; +} + + + + +// create text which sits in 3D space such as would be inserted into a normal model +osg::Group* create3DText(const osg::Vec3& center,float radius) +{ + + osg::Geode* geode = new osg::Geode; + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Examples of how to set up axis/orientation alignments +// + + float characterSize=radius*0.2f; + + osg::Vec3 pos(center.x()-radius*.5f,center.y()-radius*.5f,center.z()-radius*.5f); + + osgText::Text* text1 = new osgText::Text; + text1->setFont("fonts/times.ttf"); + text1->setCharacterSize(characterSize); + text1->setPosition(pos); + text1->setAxisAlignment(osgText::Text::XY_PLANE); + text1->setText("XY_PLANE"); + geode->addDrawable(text1); + + osgText::Text* text2 = new osgText::Text; + text2->setFont("fonts/times.ttf"); + text2->setCharacterSize(characterSize); + text2->setPosition(pos); + text2->setAxisAlignment(osgText::Text::YZ_PLANE); + text2->setText("YZ_PLANE"); + geode->addDrawable(text2); + + osgText::Text* text3 = new osgText::Text; + text3->setFont("fonts/times.ttf"); + text3->setCharacterSize(characterSize); + text3->setPosition(pos); + text3->setAxisAlignment(osgText::Text::XZ_PLANE); + text3->setText("XZ_PLANE"); + geode->addDrawable(text3); + + + osgText::Text* text4 = new osgText::Text; + text4->setFont("fonts/times.ttf"); + text4->setCharacterSize(characterSize); + text4->setPosition(center); + text4->setAxisAlignment(osgText::Text::SCREEN); + text4->setText("SCREEN"); + geode->addDrawable(text4); + + osg::ShapeDrawable* shape = new osg::ShapeDrawable(new osg::Sphere(center,characterSize*0.2f)); + shape->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::ON); + geode->addDrawable(shape); + + + osg::Group* rootNode = new osg::Group; + rootNode->addChild(geode); + + return rootNode; +} int main( int argc, char **argv ) { + // initialize the GLUT glutInit( &argc, argv ); - // get the fontName - if(argc > 1) - timesFont=argv[1]; - if(argc > 2) - arialFont=argv[2]; - if(argc > 3) - { - gFontSize=atoi(argv[3]); - if(gFontSize<=4) - gFontSize=8; - } - if(argc > 4) - { - gFontSize1=atoi(argv[3]); - if(gFontSize1<=4) - gFontSize1=8; - } - - osg::Group* rootNode = new osg::Group; - osg::Group* scene2d = new osg::Group; - osg::MatrixTransform* textGroup = new osg::MatrixTransform; - - // set the name for the hole group - rootNode->setName("sceneGroup"); - - // turn off the culling - // turn off the light - osg::StateSet* gstate = new osg::StateSet; - gstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); - gstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF); - gstate->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF); - rootNode->setStateSet(gstate); - scene2d->setStateSet(gstate); - - // setup the sceneData - setScene(textGroup); - textGroup->preMult(osg::Matrix::rotate(osg::inDegrees(90.0f),1.0f,0.0f,0.0f)); - rootNode->addChild(textGroup); - - // setup the 2dNode - set2dScene(scene2d); + // create the commandline args. + std::vector commandLine; + for(int i=1;isetBackgroundColor(osg::Vec4(.2,.2,.2,1)); -*/ - viewer.addViewport( rootNode,0.0,0.0,0.5,0.5); - viewer.addViewport( rootNode,0.5,0.0,0.5,0.5); - viewer.addViewport( rootNode,0.0,0.5,1.0,0.5); - viewer.addHUD(scene2d); + // configure the viewer from the commandline arguments, and eat any + // parameters that have been matched. + viewer.readCommandLine(commandLine); + + // configure the plugin registry from the commandline arguments, and + // eat any parameters that have been matched. + osgDB::readCommandLine(commandLine); + + // load the nodes from the commandline arguments. + osg::ref_ptr rootNode = osgDB::readNodeFiles(commandLine); + + // prepare scene. + { + + osg::Vec3 center(0.0f,0.0f,0.0f); + float radius = 1.0f; + + if (rootNode.valid()) + { + // optimize the scene graph, remove rendundent nodes and state etc. + osgUtil::Optimizer optimizer; + optimizer.optimize(rootNode.get()); + + const osg::BoundingSphere& bs = rootNode->getBound(); + center = bs.center(); + radius = bs.radius(); + } + + // make sure the root node is group so we can add extra nodes to it. + osg::Group* group = dynamic_cast(rootNode.get()); + if (!group) + { + group = new osg::Group; + + if (rootNode.valid()) group->addChild(rootNode.get()); + + rootNode = group; + } + + { + // create the hud. + osg::Projection* projection = new osg::Projection; + projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024)); + + osg::MatrixTransform* modelview_abs = new osg::MatrixTransform; + modelview_abs->setReferenceFrame(osg::Transform::RELATIVE_TO_ABSOLUTE); + modelview_abs->setMatrix(osg::Matrix::identity()); + + modelview_abs->addChild(createHUDText()); + + projection->addChild(modelview_abs); + + group->addChild(projection); + } + + group->addChild(create3DText(center,radius)); + + } + + // add a viewport to the viewer and attach the scene graph. + viewer.addViewport( rootNode.get() ); + // register trackball, flight and drive. viewer.registerCameraManipulator(new osgGA::TrackballManipulator); viewer.registerCameraManipulator(new osgGA::FlightManipulator); viewer.registerCameraManipulator(new osgGA::DriveManipulator); + // open the viewer window. viewer.open(); + + // fire up the event loop. viewer.run(); return 0; diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index d21e16e86..1fc91c309 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -129,6 +129,7 @@ void Font::addGlyph(unsigned int width, unsigned int height, unsigned int charco glyphTexture->setStateSet(stateset); stateset->setMode(GL_BLEND,osg::StateAttribute::ON); stateset->setTextureAttributeAndModes(0,glyphTexture,osg::StateAttribute::ON); + stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); if (!glyphTexture->getSpaceForGlyph(glyph,posX,posY)) { diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 95167c46a..c2efa3146 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -434,6 +434,8 @@ void Text::drawImplementation(osg::State& state) const { bool first = false; + + state.disableAllVertexArrays(); for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin(); titr!=_textureGlyphQuadMap.end();