OSG绘制几何体学习总结(超全)

在osg中,场景图形采用一种自顶向下的,分层的树状数据结构来组织空间数据集,以提高渲染的效率

场景图形树结构的顶部是一个根节点,从根节点向下延伸,各个组节点中均包含了几何信息和用于控制其外观的渲染状态信息。根节点和各个组节点都可以有零个(实际上是没有执行任何操作)或多个子成员。在场景图形的最底部,各个叶节点包含了构成场景中物体的实际几何信息。

首先,必须明确的是,在应用程序中所有几何体的渲染都必须与Geode节点相关联。在osg::Geode类中,也提供了addDrawable()函数来关联应用程序中需要渲染的几何体信息。一个Geode可以包含多个Drawable,Geode维护了一个Drawable的列表。因此在OSG中我们想要绘制诸如三角形等.最终需要使用的肯定还是Geode叶子节点.然后将Drawable通过addDrawable()方法加入Geode下…实际上要生成几何体adddrawable()的要么是一个Geomety,要么是一个shapedrawable。

在osg中,通常有三种生成几何体的手段:一是松散封装的OpenGL绘图基元osg::Geometry,二是使用OSG中预定义的基本几何体;三是从文件中导入场景模型。

不管是松散封装的OpenGL的绘图基元,还是osg自己预定义的几何体,其基类都是osg::Drawable,它派生自osg::Object(该类派生自osg::referenced),具体继承关系如下图所示,

注意:最常用的是DrawPixels,Geometry,shapedrawable,osgText::TextBase

其中:DrawPixels用于绘制图像,具体用法如下:

osg::DrawPixels* pixels = new osg::DrawPixels();pixels->setPosition(osg::Vec3((float)vX[0],(float)vY[1] ,(float)vZ[1]));QString imagePath = ::GetImagePath() + pWell->GetWellSymbol();pixels->setImage(osgDB::readImageFile(imagePath.toStdString()));//声明一个图片节点osg::Geode* imagNode = new osg::Geode();imagNode->addDrawable(pixels);

osgText用于绘制文字,具体用法如下:

QString strFont1 = ::GetImagePath() + "fonts/MicroSoftYahei.ttf";QTextCodec *code = QTextCodec::codecForName("gb18030");std::string strFont2 = strFont1.toStdString();if( code ){strFont2 = code->fromUnicode(strFont1).data();}{m_pText = new osgText::Text;m_pText->setDataVariance(osg::Object::DYNAMIC);//p->setUseDisplayList(false);m_pText->setFont(strFont2 );m_pText->setDrawMode(osgText::Text::TEXT);m_pText->setFontResolution(15,15);m_pText->setCharacterSize(15);m_pText->setAlignment(osgText::Text::CENTER_CENTER );m_pText.setAxisAlignment(osgText::Text::SCREEN);//让文字所在平面始终对着屏幕m_pText->setColor(osg::Vec4f(0,0,0,1) );}m_pGeode = new osg::Geode();m_pGeode->clone( osg::CopyOp::DEEP_COPY_ALL );m_pGeode->addDrawable( m_pText );m_pSwitch = new osg::Switch;m_pSwitch->addChild( m_pGeode );

下面重点讲解Geometry和ShapeDrawable。

在实际应用中,往场景里面添加一个几何体,都必须先定义个geode,,

然后要么用自定义几何体osg::Shape,使用方式:geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::vec3(0.0f,0.0f,0.0f),radius),hints.get()));

osg中提供了大量的预定义几何体,来简化场景的绘制,继承关系如图所示。如果要渲染这些几何体,必须将其挂到某个geode下面,但是geode只能通过adddrawable添加osg::drawable类型,因此实际应用中提供了osg::ShapeDrawable来完成这个功能。在该类的构造函数中提供了关联osg::Shape的方法:

ShapeDrawable(Shape * shape,TessellationHints * hints=0)//第一个参数即为要绘制的几何体,第二个为网格化类,主要用于设置几何体的精细程度

要么用Geometry,使用方式:

osg::ref_ptr<osg::Geode> geode1 = new osg::Geode();osg::ref_ptr<osg::Geometry> geom1 = new osg::Geometry();//创建顶点数组osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array();v->push_back(osg::Vec3(458000,0,-1500));v->push_back(osg::Vec3(458000,0,-2750));v->push_back(osg::Vec3(452000,0,-2750));v->push_back(osg::Vec3(452000,0,-1500));geom1->setVertexArray(v.get());//设置颜色数组osg::ref_ptr<osg::Vec4Array> vc = new osg::Vec4Array();vc->push_back(osg::Vec4(1.0f,0.0f,0.0f,1.0f));vc->push_back(osg::Vec4(0.0f,1.0f,0.0f,1.0f));vc->push_back(osg::Vec4(0.0f,0.0f,1.0f,1.0f));vc->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));geom1->setColorArray(vc.get());geom1->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

//设置法线数组osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array();nc->push_back(osg::Vec3(0,1,0));geom1->setNormalArray(nc.get());geom1->setNormalBinding(osg::Geometry::BIND_OVERALL);//添加图元,绘图基元为四边形geom1->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));geode1->addDrawable(geom1.get());m_pRootSwitch->addChild(geode1);

,绑定数据的方式有以下几种:

BIND_OFF

取消绑定

此时,颜色数据或者法线数据与顶点数据完全没有关系,顶点数据的颜色和法线方向完全由缺省值决定。

BIND_OVERALL

绑定全部几何体

BIND_PER_PRIMITIVE

绑定逐个几何体

BIND_PER_VERTEX

绑定逐个点

逐点绑定。比如上面的例子,将四个颜色数据分别绑定到四个顶点坐标,可以实现顶点颜色之间的过渡效果。

osg::PrimitiveSet类,该类主要松散封装了OpenGL的绘图基元,通过指定绘图基元来指定几何体顶点将采用哪一种或几种基元绘制。继承关系如下图所示,

无论如何,没有人有办法把自己抑或他人的刺拔掉。那是一碰便痛的软肋,

OSG绘制几何体学习总结(超全)

相关文章:

你感兴趣的文章:

标签云: