OSG项目经验2<在场景中添加文字面版>
2015-06-01 16:51
447 查看
添加文字版需要用到osg的三个名字空间:
osgText::Text,这个类用来添加文字和设置文字的一些属性;
osg::Geometry,这个类用来画常见的图形;
osg/ShapeDrawable,通过这个类也可以画一些常见的图形,并且可以吧Geometry加进osg::Geode节点中;
下面先简要介绍一下这三个命名空间;
1、osgText::Text:见http://www.cnblogs.com/xiaocainiao2hao/p/4544273.html
2、OSG::Gemotery
用户使用Gemotery类,可以通过制定顶点、颜色和法线的方式,绘制简单的多边形,然后通过Geode->addDrawable()方法,把绘制的多边形添加到节点中。
我在项目中仅仅画了矩形,然后通过设置geo的各个属性来达到想要的效果,这在后面的代码中会加以介绍。如果想了解更多的关于osg::Geometry的相关知识,请查看www.baidu.com。
3、osg::ShapeDrawable类
这个没啥好介绍的,也是画一些节本的图形,不果geode要调用它的一个方法比较有用
geode->addDrawable(osg::Geometry geo)
这个可以把我们自己画的Gemotery图形加到节点中。
下面通过部分代码来对这三个类的应用加以介绍:
在项目经验1中,我们已经能够通过自定义的CPickHandler()回调来达到我们在场景中用鼠标点击某个点,就能得到点击处的屏幕坐标,进而转换为世界坐标,而且我们能够通过模型的相关信息(我用的是模型的名字)来确定我们选择的是哪个模型,进而对我们的选择事件作出相应。
那么,我们首先在我们选择的模型上加上一个信息展示面板,展示模型的相关信息。
第一步,我们需要获得我们选择的模型的世界坐标:
我们可以通过center这个坐标获得我们选择节点的世界坐标,通过下面一句:
然后我们就可以通过这个世界坐标在该位置添加文字面板了。
下写一个添加文字的方法:
然后我们可以通过调用这两个函数添加文字:
在上面的代码中的wordMark.x()和y、z坐标加减值都是我根据显示效果自己调整的位置。在具体情况下需要自己确定值。
关于
createTexturedQuadGeometry(const Vec3 & corner,const Vec3 & widthVec,const Vec3 & heightVec,float l,float b,float r,float t );
其中corner是起点(矩形的左下角),然后从这个起点按照widthVec和heightVec来画出一个矩形,我一般设置
l,b一般都取0.0,r,t如果不相等,那么二维的贴图会变成长方形。也就是说,我的黑白棋盘格,会变成黑白长方格。相等的话,就会变成黑白正方格。
另外colorArray 对象的颜色值
osgText::Text,这个类用来添加文字和设置文字的一些属性;
osg::Geometry,这个类用来画常见的图形;
osg/ShapeDrawable,通过这个类也可以画一些常见的图形,并且可以吧Geometry加进osg::Geode节点中;
下面先简要介绍一下这三个命名空间;
1、osgText::Text:见http://www.cnblogs.com/xiaocainiao2hao/p/4544273.html
2、OSG::Gemotery
用户使用Gemotery类,可以通过制定顶点、颜色和法线的方式,绘制简单的多边形,然后通过Geode->addDrawable()方法,把绘制的多边形添加到节点中。
我在项目中仅仅画了矩形,然后通过设置geo的各个属性来达到想要的效果,这在后面的代码中会加以介绍。如果想了解更多的关于osg::Geometry的相关知识,请查看www.baidu.com。
3、osg::ShapeDrawable类
这个没啥好介绍的,也是画一些节本的图形,不果geode要调用它的一个方法比较有用
geode->addDrawable(osg::Geometry geo)
这个可以把我们自己画的Gemotery图形加到节点中。
下面通过部分代码来对这三个类的应用加以介绍:
在项目经验1中,我们已经能够通过自定义的CPickHandler()回调来达到我们在场景中用鼠标点击某个点,就能得到点击处的屏幕坐标,进而转换为世界坐标,而且我们能够通过模型的相关信息(我用的是模型的名字)来确定我们选择的是哪个模型,进而对我们的选择事件作出相应。
那么,我们首先在我们选择的模型上加上一个信息展示面板,展示模型的相关信息。
第一步,我们需要获得我们选择的模型的世界坐标:
osg::Vec3 center; // osg中的坐标是三维的,所以我们需要定义一个三维向量center用来存储获得的坐标 int NodeNum; center = mRoot->getChild(NodeNum)->computeBound()._center; //获得鼠标点击模型的包围盒的中心处坐标,NodeNum是我加载模型的时候模型在节点中的序号
我们可以通过center这个坐标获得我们选择节点的世界坐标,通过下面一句:
osg::Vec3 wordMark = mRoot->getChild(NodeNum)->getBound().center()*osg::computeLocalToWorld(mGroup->getChild(NodeNum)->getParentalNodePaths()[0]);//获得节点的世界坐标
然后我们就可以通过这个世界坐标在该位置添加文字面板了。
下写一个添加文字的方法:
void CreatText(osgText::Text& textObject,osgText::Font* font,float size,const osg::Vec3& pos ) { textObject.setFont(font);// 读入字体 textObject.setCharacterSize(size);//字体大小 textObject.setPosition(pos); textObject.setColor(osg::Vec4(0.0,1.0,0.0,1.0)); textObject.setAlignment(osgText::Text::LEFT_BOTTOM);//文字对齐方向 textObject.setAutoRotateToScreen(true);//跟随视角不断变化,但离物体越远,文字越小 textObject.setAxisAlignment(osgText::Text::XZ_PLANE);//获取文字对称成方式 }//在这个函数中也可以根据自己的需要使用text的其他方法,如文字描边:textObject.setBackdropType(),给文字加上边框:textObject.setDrawMode()等 void createContent(osgText::Text& textObject,const char* string) { int requiredSize=mbstowcs(NULL,string,0); //如果mbstowcs第一参数为NULL那么返回字符串的数目 wchar_t* wText=new wchar_t[requiredSize+1]; mbstowcs(wText,string,requiredSize+1) ;//由char转换成wchar类型 textObject.setText(wText); delete wText; }
然后我们可以通过调用这两个函数添加文字:
const char* textString={ "我选中的节点是这个;\n" "先画一个文字面板;\n" "再添加文字;\n" "然后把文字和面板都添加到geode中;\n" "最后把geode加载到mRoot中" }; const char* titleString={ "文字面板" }; osgText::Font* fontHei = osgText::readFontFile("simhei.ttf"); //读入字体 osg::ref_ptr<osgText::Text> text = new osgText::Text; //新建一个text对象 CreatText(*text,fontHei,350.0,wordMark); //调用CreatText()方法,创建一个文字对象,wordMark就是我们上步计算的选择节点的世界坐标 createContent(*text,textString); osg::ref_ptr<osgText::Text> title = new osgText::Text; setupProperties(*title,fontHei,350.0,osg::Vec3(wordMark.x()+1100,wordMark.y()-2508,wordMark.z()+1600)); createContent(*title,titleString); title->setColor(osg::Vec4(1.0,0.0,0.0,1.0)); osg::ref_ptr<osg::Geode> geode3 = new osg::Geode; //创建一个geode对象,用来加载text和Gemotery对象 //给文字添加底板 osg::ref_ptr<osg::Geometry> geo = new osg::Geometry; //创建一个Gemotery对象 osg::Vec4Array* colorArray = new osg::Vec4Array; //创建一个Vec4Array对象,存放颜色信息 geo = osg::createTexturedQuadGeometry(osg::Vec3(wordMark.x(),wordMark.y()+6,wordMark.z()+1400),osg::Vec3(4500,0.0,0.0),osg::Vec3(0.0,0.0,200),1.0,1.0); //画一个小矩形,用来摆放title,后面会对createTexturedQuadGeometry里面的参数做介绍 colorArray->push_back(osg::Vec4(0.0,1.0,0.0,1.0)); //给colorArray赋值,0101是绿色 geo->setColorArray(colorArray); //给画的矩形设置颜色 geode3->addDrawable(osg::createTexturedQuadGeometry(osg::Vec3(wordMark.x(),wordMark.y()+8,wordMark.z()-130.0),osg::Vec3(4500,0.0,0.0),osg::Vec3(0.0,0.0,1600),1.0,1.0)); //再画一个大矩形,用来放其它文字信息,并且把矩形加进geode对象中 geode3->addDrawable(geo.get()); //把小矩形也加载进geode geode3->addDrawable(text.get()); geode3->addDrawable(title.get()); mRoot->addChild(geode3); //把文字面板加进mRoot中
在上面的代码中的wordMark.x()和y、z坐标加减值都是我根据显示效果自己调整的位置。在具体情况下需要自己确定值。
关于
createTexturedQuadGeometry(const Vec3 & corner,const Vec3 & widthVec,const Vec3 & heightVec,float l,float b,float r,float t );
其中corner是起点(矩形的左下角),然后从这个起点按照widthVec和heightVec来画出一个矩形,我一般设置
widthVec=osg::Vec3(num1,0,0); //这个num1就是矩形的长 heightVec=osg::Vec3(0,0,num2); //这个num2就是矩形的高
l,b一般都取0.0,r,t如果不相等,那么二维的贴图会变成长方形。也就是说,我的黑白棋盘格,会变成黑白长方格。相等的话,就会变成黑白正方格。
另外colorArray 对象的颜色值
colarray->push_back(osg::Vec4(1.0, 0.0, 0.0, 1.0)); //Red colarray->push_back(osg::Vec4(0.0, 1.0, 0.0, 1.0)); //Green colarray->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0)); //Blue colarray->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0)); //White
相关文章推荐
- CodeForge源码分享
- Node.js安装和入门
- 【C语言探索之旅】 第三部分第一课:SDL开发游戏之安装SDL
- python直接按行读取gz压缩文件中的文本文件的数据
- Java编码问题汇总
- The Internet Communications Engine (Ice) 跨平台异构通讯方案 第二弹-Hello world! - Uzumaki
- “ 戏"说 明星”与“麻将
- Cannot resolve the collation conflict between "SQL_Latin1_Gen
- DIKW模型
- file压缩
- 人人都是网站分析师:从分析师的视角理解网站和解读数据
- break continue switch 语句的使用
- 多次格式化namenode之后datanode无法启动
- 马化腾回忆创业:曾假扮女孩子陪聊
- linux学习笔记—逻辑操作符和管道符
- 在QT下测试openni+opencv,显示采集的深度图和彩色图
- LeetCode_5---Longest Palindromic Substring (求最长回文子串)
- 为什么斗地主越来越受人喜欢
- 面试题26:复杂链表的赋值
- ios Undefined symbols for architecture arm64:错误解决