OpenSceneGraph实现的NeHe OpenGL教程 - 第十三课

  • 简介

NeHe这节课主要讨论如何使用OpenGL显示2D文字。OpenGL显示2D文字是通过wglUseFontBitmaps函数创建了一系列的显示列表来实现的。通过阅读NeHe教程,读者应该能感觉到在OpenGL中显示文字还是比较麻烦的。在OSG中显示2D文字相对来说比较简单,OSG提供了专门用来处理文字的库osgText(包括二维和三维字体)

  • 实现

首先创建文字节点,由于osgText::Text继承于osg::Drawable可绘制物体,因此创建文本之后直接将其添加到叶节点中

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Group *root = new osg::Group;  
  2.   
  3. osg::MatrixTransform *moveMT = new osg::MatrixTransform;  
  4. moveMT->setMatrix(osg::Matrix::translate(0, 0, -10));  
  5. root->addChild(moveMT);  
  6.   
  7. osg::Geode *fontGeode = new osg::Geode;  
  8.   
  9. osgText::Text *text = new osgText::Text;  
  10. text->setCharacterSize(0.4f);  
  11. text->setUpdateCallback(new FontColorCallback);  
  12. text->setText("OpenGL NeHe");  
  13. text->setFont("fonts/arial.ttf");  
  14. fontGeode->addDrawable(text);  
  15.   
  16. moveMT->addChild(fontGeode);  
  17.   
  18. return root;  
对于OSG中的Text类,它提供了丰富的成员函数允许用户自由地调整排版格式、采用不同的位置和姿态、使用不同的颜色等操作。

由于场景中需要不断修改字体的颜色,我们使用Drawable的UpdateCallback来完成

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class FontColorCallback : public osg::Drawable::UpdateCallback  
  2. {  
  3. public:  
  4.   
  5.     virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)  
  6.     {  
  7.         if (dynamic_cast<osgText::Text*>(drawable))  
  8.         {  
  9.             osgText::Text *text = dynamic_cast<osgText::Text*>(drawable);  
  10.             text->setColor(osg::Vec4(1.0f*float(cos(cnt1)),1.0f*float(sin(cnt2)),1.0f-0.5f*float(cos(cnt1+cnt2)), 1));  
  11.   
  12.             std::stringstream os;  
  13.             std::string str;  
  14.             os.precision(2);  
  15.             os << std::fixed << "Active OpenGL Text With NeHe - " << cnt1;  
  16.             str = os.str();  
  17.   
  18.             text->setText(str);  
  19.             text->setPosition(osg::Vec3(-4.5f+0.5f*float(cos(cnt1)), 1.92f*float(sin(cnt2)),0));  
  20.             cnt1+=0.051f;  
  21.             cnt2+=0.005f;     
  22.   
  23.         }  
  24.     }  
  25. };  
在每帧中修改字体的颜色和位置,与NeHe教程中的模式一样

最后编译运行程序:


附:本课源码(源码中可能存在不足和错误,仅供参考)

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include "../osgNeHe.h"  
  2.   
  3. #include <QtCore/QTimer>  
  4. #include <QtGui/QApplication>  
  5. #include <QtGui/QVBoxLayout>  
  6.   
  7. #include <osgViewer/Viewer>  
  8. #include <osgDB/ReadFile>  
  9. #include <osgQt/GraphicsWindowQt>  
  10.   
  11. #include <osg/MatrixTransform>  
  12.   
  13. #include <osgDB/ReadFile>  
  14. #include <osgText/Text>  
  15.   
  16. #include <iostream>  
  17. #include <sstream>  
  18.   
  19. float cnt1, cnt2;  
  20.   
  21. class FontColorCallback : public osg::Drawable::UpdateCallback  
  22. {  
  23. public:  
  24.   
  25.     virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)  
  26.     {  
  27.         if (dynamic_cast<osgText::Text*>(drawable))  
  28.         {  
  29.             osgText::Text *text = dynamic_cast<osgText::Text*>(drawable);  
  30.             text->setColor(osg::Vec4(1.0f*float(cos(cnt1)),1.0f*float(sin(cnt2)),1.0f-0.5f*float(cos(cnt1+cnt2)), 1));  
  31.   
  32.             std::stringstream os;  
  33.             std::string str;  
  34.             os.precision(2);  
  35.             os << std::fixed << "Active OpenGL Text With NeHe - " << cnt1;  
  36.             str = os.str();  
  37.   
  38.             text->setText(str);  
  39.             text->setPosition(osg::Vec3(-4.5f+0.5f*float(cos(cnt1)), 1.92f*float(sin(cnt2)),0));  
  40.             cnt1+=0.051f;  
  41.             cnt2+=0.005f;     
  42.   
  43.         }  
  44.     }  
  45. };  
  46.   
  47.   
  48.   
  49. class ViewerWidget : public QWidget, public osgViewer::Viewer  
  50. {  
  51. public:  
  52.     ViewerWidget(osg::Node *scene = NULL)  
  53.     {  
  54.         QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,100,100), scene);  
  55.   
  56.         QVBoxLayout* layout = new QVBoxLayout;  
  57.         layout->addWidget(renderWidget);  
  58.         layout->setContentsMargins(0, 0, 0, 1);  
  59.         setLayout( layout );  
  60.   
  61.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  62.         _timer.start( 10 );  
  63.     }  
  64.   
  65.     QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )  
  66.     {  
  67.         osg::Camera* camera = this->getCamera();  
  68.         camera->setGraphicsContext( gw );  
  69.   
  70.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  71.   
  72.         camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 1.0) );  
  73.         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );  
  74.         camera->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  75.         camera->setViewMatrixAsLookAt(osg::Vec3d(0, 0, 1), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));  
  76.   
  77.         this->setSceneData( scene );  
  78.   
  79.         return gw->getGLWidget();  
  80.     }  
  81.   
  82.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  83.     {  
  84.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  85.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  86.         traits->windowName = name;  
  87.         traits->windowDecoration = windowDecoration;  
  88.         traits->x = x;  
  89.         traits->y = y;  
  90.         traits->width = w;  
  91.         traits->height = h;  
  92.         traits->doubleBuffer = true;  
  93.         traits->alpha = ds->getMinimumNumAlphaBits();  
  94.         traits->stencil = ds->getMinimumNumStencilBits();  
  95.         traits->sampleBuffers = ds->getMultiSamples();  
  96.         traits->samples = ds->getNumMultiSamples();  
  97.   
  98.         return new osgQt::GraphicsWindowQt(traits.get());  
  99.     }  
  100.   
  101.     virtual void paintEvent( QPaintEvent* event )  
  102.     {   
  103.         frame();   
  104.     }  
  105.   
  106. protected:  
  107.   
  108.     QTimer _timer;  
  109. };  
  110.   
  111.   
  112.   
  113. osg::Node*  buildScene()  
  114. {  
  115.     osg::Group *root = new osg::Group;  
  116.   
  117.     osg::MatrixTransform *moveMT = new osg::MatrixTransform;  
  118.     moveMT->setMatrix(osg::Matrix::translate(0, 0, -10));  
  119.     root->addChild(moveMT);  
  120.   
  121.     osg::Geode *fontGeode = new osg::Geode;  
  122.   
  123.     osgText::Text *text = new osgText::Text;  
  124.     text->setCharacterSize(0.4f);  
  125.     text->setUpdateCallback(new FontColorCallback);  
  126.     text->setText("OpenGL NeHe");  
  127.     text->setFont("fonts/arial.ttf");  
  128.     fontGeode->addDrawable(text);  
  129.   
  130.     moveMT->addChild(fontGeode);  
  131.   
  132.     return root;  
  133. }  
  134.   
  135.   
  136.   
  137. int main( int argc, char** argv )  
  138. {  
  139.     QApplication app(argc, argv);  
  140.     ViewerWidget* viewWidget = new ViewerWidget(buildScene());  
  141.     viewWidget->setGeometry( 100, 100, 640, 480 );  
  142.     viewWidget->show();  
  143.     return app.exec();  
  144. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值