当前位置:高等教育资讯网  >  中国高校课件下载中心  >  大学文库  >  浏览文档

上海交通大学:《创新思维与现代设计》教学资源_编程资料_OSG资料_OSG开源教程

资源类别:文库,文档格式:DOC,文档页数:49,文件大小:351KB,团购合买
点击下载完整版文档(DOC)

0SG开源教程 整理:荣明、王伟 北京 2008年4月

OSG 开源教程 整理:荣明、王伟 北 京 2008 年 4 月

序 第一次接触0SG是在2001年,当时开源社区刚刚兴起,还没有现在这 么火。下载了0SG源码,但是在看了几个Demo之后,感觉没有什么特别之 处。时隔七年之后,我再次将目光投向OSG,发现OSG确实有其独到之处, 很多3D效果已经不弱于甚至超过商业软件,有感于开源力量的巨大。但是, 与当前主流3D商业软件如Vega、VegaPrime、VTree、Performer等相比, 开源软件的缺点也很明显,其中文档缺乏可谓其致命弱点之一。开发者只 能从浩瀚的源码中,进行编程的学习,效率不高。 OSG组织也意识到这一点,不断推出一些官方教程,网络上有很多OSG 爱好者发布的心得和教程。我收集、整理了许多学习资料,其中美国海军 研究生院发布的0$G教程非常好,可作为0$G的官方教程的一个很好补充。 它共有十一个专题,结合例子程序,一步步教你如何进行OSG的开发。我 将其编辑成一个较为完善的教材,供大家学习。在教材整理过程中,王伟 调试了源程序,对该书编辑和修订做了大量的工作;实验室的学生杨宇蒙、 冯锐、章仕锋、李永川和李益强阅读了本书,并提出了宝贵的修改意见, 在此一并表示感谢。 希望这本小册子能对大家学习OSG编程起到一定的帮助作用。 谢谢大家阅读本书! 荣明 二00八年四月于崔春园 Email:rong_ming@sina.com (本书的资料全部来自互联网,仅供个人学习交流使用。感谢竹林小舍、array翻译了Navy的教程。)

1 序 第一次接触 OSG 是在 2001 年,当时开源社区刚刚兴起,还没有现在这 么火。下载了 OSG 源码,但是在看了几个 Demo 之后,感觉没有什么特别之 处。时隔七年之后,我再次将目光投向 OSG,发现 OSG 确实有其独到之处, 很多 3D 效果已经不弱于甚至超过商业软件,有感于开源力量的巨大。但是, 与当前主流 3D 商业软件如 Vega、VegaPrime、VTree、Performer 等相比, 开源软件的缺点也很明显,其中文档缺乏可谓其致命弱点之一。开发者只 能从浩瀚的源码中,进行编程的学习,效率不高。 OSG 组织也意识到这一点,不断推出一些官方教程,网络上有很多 OSG 爱好者发布的心得和教程。我收集、整理了许多学习资料,其中美国海军 研究生院发布的 OSG 教程非常好,可作为 OSG 的官方教程的一个很好补充。 它共有十一个专题,结合例子程序,一步步教你如何进行 OSG 的开发。我 将其编辑成一个较为完善的教材,供大家学习。在教材整理过程中,王伟 调试了源程序,对该书编辑和修订做了大量的工作;实验室的学生杨宇蒙、 冯锐、章仕锋、李永川和李益强阅读了本书,并提出了宝贵的修改意见, 在此一并表示感谢。 希望这本小册子能对大家学习 OSG 编程起到一定的帮助作用。 谢谢大家阅读本书! 荣 明 二 OO 八年四月于崔春园 Email:rong_ming@sina.com (本书的资料全部来自互联网,仅供个人学习交流使用。感谢竹林小舍、array 翻译了 Navy 的教程。)

目录 l.使用Open Scene Graph几何 ..1 1.1背景 1.2代码 .1 2.使用StateSet产生有纹理的几何体 2.1本章目标 .4 2.2背景. 4 2.3加载纹理,生成状态集合并将他们附加到节点上 6 3.使用Shape,改变state. P 3.1本章目标 8 3.2使用Shape类 .8 3.3设置状态 .9 4.更多的StateSet.. 10 4.1StateSet如何工作 10 4.2例子及代码.… 10 5.从文件中加载模型并放入到场景中.… .12 5.1本章目标 12 5.2加载几何模型并加入到场景中 12 6.osg Text、.HlUD、RenderBins. .15 6.1本章目标 15 6.2摘要… .15 6.3代码 .15 7.搜索并控制开关和DOF(自由度)节点(Finding and Manipulating a Switch and DOF Node)20 7.1搜索场景图形中的个有名节点20 72按照“访问器"模式搜索有名节点 22 8.使用更新回调来更改模型…… .26 81本章日标 26 8.2回调概览. 26 83创建一个更新回调. 26 9.处理键盘输入 .29 9.1本章目标 .29 9.2GUI(图形用户接口)事件处理器: 29 9.3简单的键盘接口类 .30 9.4使用键盘接口类.… 31 9.5处理键盘输入实现更新回调 32 9.5.1本节目标.… .32 9.5.2问题的提出 32 9.5.3解决方案. .33 l0.使用自定义矩阵来放置相机(Positioning a Camera with a User-Defined Matrix) 36 10.1本章目标 .36 10.2设置矩阵的方向和位置 36 10.3声明一个用于设置相机的矩阵 37 10.4使用矩阵设置视口摄相机.… 38 2

2 目录 1.使用 Open Scene Graph 几何.................................................................................................................... 1 1.1 背景....................................................................................................................................................1 1.2 代码....................................................................................................................................................1 2.使用 StateSet 产生有纹理的几何体........................................................................................................ 4 2.1 本章目标............................................................................................................................................4 2.2 背景....................................................................................................................................................4 2.3 加载纹理,生成状态集合并将他们附加到节点上.......................................................................6 3.使用 Shape,改变 state............................................................................................................................ 8 3.1 本章目标............................................................................................................................................8 3.2 使用 Shape 类....................................................................................................................................8 3.3 设置状态............................................................................................................................................9 4.更多的 StateSet........................................................................................................................................10 4.1StateSet 如何工作......................................................................................................................... 10 4.2 例子及代码......................................................................................................................................10 5.从文件中加载模型并放入到场景中........................................................................................................ 12 5.1 本章目标..........................................................................................................................................12 5.2 加载几何模型并加入到场景中..................................................................................................... 12 6.osg Text、HUD、RenderBins.................................................................................................................. 15 6.1 本章目标..........................................................................................................................................15 6.2 摘要..................................................................................................................................................15 6.3 代码..................................................................................................................................................15 7.搜索并控制开关和 DOF(自由度)节点(Finding and Manipulating a Switch and DOF Node) 20 7.1 搜索场景图形中的一个有名节点.................................................................................................. 20 7.2 按照“访问器”模式搜索有名节点...................................................................................................22 8.使用更新回调来更改模型........................................................................................................................ 26 8.1 本章目标...........................................................................................................................................26 8.2 回调概览...........................................................................................................................................26 8.3 创建一个更新回调.......................................................................................................................... 26 9.处理键盘输入..............................................................................................................................................29 9.1 本章目标...........................................................................................................................................29 9.2 GUI(图形用户接口)事件处理器:...........................................................................................29 9.3 简单的键盘接口类..........................................................................................................................30 9.4 使用键盘接口类.............................................................................................................................. 31 9.5 处理键盘输入实现更新回调......................................................................................................... 32 9.5.1 本节目标...............................................................................................................................32 9.5.2 问题的提出...........................................................................................................................32 9.5.3 解决方案...............................................................................................................................33 10.使用自定义矩阵来放置相机(Positioning a Camera with a User-Defined Matrix)...........................36 10.1 本章目标.........................................................................................................................................36 10.2 设置矩阵的方向和位置............................................................................................................... 36 10.3 声明一个用于设置相机的矩阵.................................................................................................... 37 10.4 使用矩阵设置视口摄相机............................................................................................................ 38

11.实现跟随节点的相机 .38 11.1本章目标. 38 112概述 38 11.3实现 39 11.4环绕(始终指向)场景中节点的相机 42 11.4.1本节目标 42 11.4.2实现.… 42

3 11. 实现跟随节点的相机..............................................................................................................................38 11.1 本章目标.........................................................................................................................................38 11.2 概述.................................................................................................................................................38 11.3 实现.................................................................................................................................................39 11.4 环绕(始终指向)场景中节点的相机........................................................................................ 42 11.4.1 本节目标.............................................................................................................................42 11.4.2 实现.....................................................................................................................................42

l.使用Open Scene Graph几何 本节涵盖了生成基本几何形状的一些方法。生成几何物体的方法有这么几种:在最底层对 OpenGL基本几何进行松散的包装,中级是使用Open Scene Graph的基本形状,以及更高级一些的 从文件读取。这篇教程涵盖的是最低层的。这种方法弹性最大但最费力。通常在Scene Graph级别, 几何形状是从文件加载的。文件加载器完成了跟踪顶点的大部分工作。 1.1背景 对一下几个类的简单解释: Geode类: geode类继承自node类。在一个Scene Graph中,node(当然包含geode)可以作为叶子节点。 Geode实例可以有多个相关的drawable。. Drawable类层次: 基类drawable是一个有六个具体子类的抽象类。 geometry类可以直接有vertex和vertex数据,或者任意个primitiveSet实例。 vertex和vertex属性数据(颜色、法线、纹理坐标)存放在数组中。既然多个顶点可以共享相 同的颜色、法线或纹理坐标,那么数组索引就可以用来将顶点数组映射到颜色、法线、或纹理坐标 数组。 PrimitiveSet类: 这个类松散的包装了OpenGL的基本图形-POINTS,LINES,LINE_STRIP,LINE LOOP,..,POLYGON. 1.2代码 以下这节代码安装了一个viewer来观察我们创建的场景,一个‘group'实例作为scene graph 的根节点,一个几何节点(geode)来收集drawable,和一个geometry实例来关联顶点和顶点数据。 (这个例子中渲染的形状是一个四面体) int main() osgProducer:Viewer viewer; osg::Group*root new osg::Group(); osg:Geode*pyramidGeode new osg:Geode(); osg:Geometry*pyramidGeometry new osg:Geometry(): 下一步,需要将锥体geometry和锥体geode关联起来,并将pyramid geode加到scene graph 的根节点上。 pyramidGeode->addDrawable(pyramidGeometry); root->addChild(pyramidGeode);

1 1.使用 Open Scene Graph 几何 本节涵盖了生成基本几何形状的一些方法。生成几何物体的方法有这么几种:在最底层对 OpenGL 基本几何进行松散的包装,中级是使用 Open Scene Graph 的基本形状,以及更高级一些的 从文件读取。这篇教程涵盖的是最低层的。这种方法弹性最大但最费力。通常在 Scene Graph 级别, 几何形状是从文件加载的。文件加载器完成了跟踪顶点的大部分工作。 1.1 背景 对一下几个类的简单解释: Geode 类: geode 类继承自 node 类。在一个 Scene Graph 中,node(当然包含 geode)可以作为叶子节点。 Geode 实例可以有多个相关的 drawable。 Drawable 类层次: 基类 drawable 是一个有六个具体子类的抽象类。 geometry 类可以直接有 vertex 和 vertex 数据,或者任意个 primitiveSet 实例。 vertex 和 vertex 属性数据(颜色、法线、纹理坐标)存放在数组中。既然多个顶点可以共享相 同的颜色、法线或纹理坐标,那么数组索引就可以用来将顶点数组映射到颜色、法线、或纹理坐标 数组。 PrimitiveSet 类: 这个类松散的包装了 OpenGL 的基本图形-POINTS,LINES,LINE_STRIP,LINE_LOOP,...,POLYGON. 1.2 代码 以下这节代码安装了一个 viewer 来观察我们创建的场景,一个‘group’实例作为 scene graph 的根节点,一个几何节点(geode)来收集 drawable,和一个 geometry 实例来关联顶点和顶点数据。 (这个例子中渲染的形状是一个四面体) ... int main() { ... osgProducer::Viewer viewer; osg::Group* root = new osg::Group(); osg::Geode* pyramidGeode = new osg::Geode(); osg::Geometry* pyramidGeometry = new osg::Geometry(); 下一步,需要将锥体 geometry 和锥体 geode 关联起来,并将 pyramid geode 加到 scene graph 的根节点上。 pyramidGeode->addDrawable(pyramidGeometry); root->addChild(pyramidGeode);

声明一个顶点数组。每个顶点由一个三元组表示一一vc3类的实例。这些三元组用 osg:Vec3 Array类的实例存贮。既然osg:Vec3 Array继承自STL的vector类,那么我们就可以使 用push_back方法来添加数组成员。push back将元素加到向量的尾端,因此第一个元素的索引是 0,第二个是1,依此类推。 使用‘z’轴向上的右手坐标系系统,下面的0..4数组元素代表着产生一个简单锥体所需的5 个点。 osg:Vec3Array*pyramidVertices new osg:Vec3Array; pyramidVertices->push_back(osg:Vec3(0,0,0));//front left pyramidVertices->push_back(osg:Vec3(10,0,0));//front right pyramidVertices->push_back(osg:Vec3(10,10,0));//back right pyramidVertices->push_back(osg:Vec3(0,10,0));//back left pyramidVertices->push_back(osg:Vec3(5,5,10));//peak 将这个顶点集合和与我们加到场景中的geode相关的geometry关联起来。 pyramidGeometry->setVertexArray(pyramidVertices ) 下一步,产生一个基本集合并将其加入到pyramid geometry中。使用pyramid的前四个点通过 DrawElementsUint类的实例来定义基座。这个类也继承自STL的vector,所以push_back方法会 顺序添加元素。为了保证合适的背面剔除,顶点的顺序应当是逆时针方向的。构造器的参数是基本 的枚举类型(和opengl的基本枚举类型一致),和起始的顶点数组索引。 osg:DrawElementsUInt*pyramidBase new osg:DrawElementsUInt (osg:PrimitiveSet:QUADS,0); pyramidBase->push back(3); pyramidBase->push_back(2); pyramidBase->push_back(1); pyramidBase->push_back(0); pyramidGeometry->addPrimitiveSet(pyramidBase); 对每个面重复相同的动作。顶点仍要按逆时针方向指定。 osg:DrawElementsUInt*pyramidFaceOne new osg:DrawElementsUInt (osg:PrimitiveSet:TRIANGLES,0); pyramidFaceOne->push_back(0); pyramidFaceOne->push_back(1); pyramidFaceOne->push_back(4): pyramidGeometry->addPrimitiveSet(pyramidFaceOne); osg:DrawElementsUInt*pyramidFaceTwo new osg:DrawElementsUInt (osg:PrimitiveSet:TRIANGLES,0); pyramidFaceTwo->push_back(1); pyramidFaceTwo->push_back(2); pyramidFaceTwo->push_back(4); pyramidGeometry->addPrimitiveSet(pyramidFaceTwo); osg:DrawElementsUInt*pyramidFaceThree new osg:DrawElementsUInt (osg:PrimitiveSet:TRIANGLES,0); pyramidFaceThree->push_back(2); pyramidFaceThree->push_back(3);

2 声 明 一 个 顶 点 数 组 。 每 个 顶 点 由 一 个 三 元 组 表 示 ——vec3 类 的 实 例 。 这 些 三 元 组 用 osg::Vec3Array 类的实例存贮。既然 osg::Vec3Array 继承自 STL 的 vector 类,那么我们就可以使 用 push_back 方法来添加数组成员。push_back 将元素加到向量的尾端,因此第一个元素的索引是 0,第二个是 1,依此类推。 使用‘z’轴向上的右手坐标系系统,下面的 0...4 数组元素代表着产生一个简单锥体所需的 5 个点。 osg::Vec3Array* pyramidVertices = new osg::Vec3Array; pyramidVertices->push_back( osg::Vec3( 0, 0, 0) ); // front left pyramidVertices->push_back( osg::Vec3(10, 0, 0) ); // front right pyramidVertices->push_back( osg::Vec3(10,10, 0) ); // back right pyramidVertices->push_back( osg::Vec3( 0,10, 0) ); // back left pyramidVertices->push_back( osg::Vec3( 5, 5,10) ); // peak 将这个顶点集合和与我们加到场景中的 geode 相关的 geometry 关联起来。 pyramidGeometry->setVertexArray( pyramidVertices ); 下一步,产生一个基本集合并将其加入到 pyramid geometry 中。使用 pyramid 的前四个点通过 DrawElementsUint 类的实例来定义基座。这个类也继承自 STL 的 vector,所以 push_back 方法会 顺序添加元素。为了保证合适的背面剔除,顶点的顺序应当是逆时针方向的。构造器的参数是基本 的枚举类型(和 opengl 的基本枚举类型一致),和起始的顶点数组索引。 osg::DrawElementsUInt* pyramidBase = new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0); pyramidBase->push_back(3); pyramidBase->push_back(2); pyramidBase->push_back(1); pyramidBase->push_back(0); pyramidGeometry->addPrimitiveSet(pyramidBase); 对每个面重复相同的动作。顶点仍要按逆时针方向指定。 osg::DrawElementsUInt* pyramidFaceOne = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0); pyramidFaceOne->push_back(0); pyramidFaceOne->push_back(1); pyramidFaceOne->push_back(4); pyramidGeometry->addPrimitiveSet(pyramidFaceOne); osg::DrawElementsUInt* pyramidFaceTwo = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0); pyramidFaceTwo->push_back(1); pyramidFaceTwo->push_back(2); pyramidFaceTwo->push_back(4); pyramidGeometry->addPrimitiveSet(pyramidFaceTwo); osg::DrawElementsUInt* pyramidFaceThree = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0); pyramidFaceThree->push_back(2); pyramidFaceThree->push_back(3);

pyramidFaceThree->push back(4); pyramidGeometry->addPrimitiveSet(pyramidFaceThree); osg:DrawElementsUInt*pyramidFaceFour new osg:DrawElementsUInt(osg:PrimitiveSet:TRIANGLES,0); pyramidFaceFour->push_back(3); pyramidFaceFour->push_back(0); pyramidFaceFour->push_back(4); pyramidGeometry->addPrimitiveSet(pyramidFaceFour) 声明并加载一个vec4为元素的数组来存储颜色。 osg:Vec4Array*colors new osg:Vec4Array; colors->push_back(osg:Vec4(1.Of,0.Of,0.Of,1.0f));//index 0 red colors->push_back(osg:Vec4(0.Of,1.0f,0.Of,1.0f))://index 1 green colors->push_back(osg:Vec4(0.Of,0.Of,1.Of,1.0f));//index 2 blue colors->push_back(osg:Vec4(1.0f,1.0f,1.0f,1.0f));//index 3 white 声明的这个变量可以将顶点数组元素和颜色数组元素匹配起来。这个容器的元素数应当和顶点数 致。这个容器是顶点数组和颜色数组的连接。这个索引数组中的条目就对应着顶点数组中的元素。 他们的值就是颜色数组中的索引。顶点数组元素与normal和纹理坐标数组的匹配也是遵循这种模 式。 注意,这种情况下,我们将5个顶点指定4种颜色。顶点数组的0和4元素都被指定为颜色数组 的0元素。 osg:TemplateIndexArray *colorIndexArray; colorIndexArray new osg:TemplateIndexArray; colorIndexArray->push_back(0);//vertex 0 assigned color array element 0 colorIndexArray->push_back(1);//vertex 1 assigned color array element 1 colorIndexArray->push_back(2);//vertex 2 assigned color array element 2 colorIndexArray->push_back(3);//vertex 3 assigned color array element 3 colorIndexArray->push_back(0);//vertex 4 assigned color array element 0 下一步,将颜色数组和geometry关联起来,将上面产生的颜色索引指定给geometry,设定绑定 模式为PER_VERTEX。 pyramidGeometry->setColorArray(colors); pyramidGeometry->setColorIndices(colorIndexArray); pyramidGeometry->setColorBinding(osg:Geometry:BIND_PER_VERTEX); osg:Vec2Array*texcoords new osg:Vec2Array(5); (*texcoords)[0].set(0.00f,0.Of); (*texcoords)[1].set(0.25f,0.Of); (*texcoords)[2].set(0.50f,0.0f); (*texcoords)[3].set(0.75f,0.0f); (*texcoords)[4].set (0.50f,1.Of); pyramidGeometry->setTexCoordArray(0,texcoords); 注:一下部分可能错误

3 pyramidFaceThree->push_back(4); pyramidGeometry->addPrimitiveSet(pyramidFaceThree); osg::DrawElementsUInt* pyramidFaceFour = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0); pyramidFaceFour->push_back(3); pyramidFaceFour->push_back(0); pyramidFaceFour->push_back(4); pyramidGeometry->addPrimitiveSet(pyramidFaceFour) 声明并加载一个 vec4 为元素的数组来存储颜色。 osg::Vec4Array* colors = new osg::Vec4Array; colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); //index 0 red colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f) ); //index 1 green colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f) ); //index 2 blue colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f) ); //index 3 white 声明的这个变量可以将顶点数组元素和颜色数组元素匹配起来。这个容器的元素数应当和顶点数 一致。这个容器是顶点数组和颜色数组的连接。这个索引数组中的条目就对应着顶点数组中的元素。 他们的值就是颜色数组中的索引。顶点数组元素与 normal 和纹理坐标数组的匹配也是遵循这种模 式。 注意,这种情况下,我们将 5 个顶点指定 4 种颜色。顶点数组的 0 和 4 元素都被指定为颜色数组 的 0 元素。 osg::TemplateIndexArray *colorIndexArray; colorIndexArray = new osg::TemplateIndexArray; colorIndexArray->push_back(0); // vertex 0 assigned color array element 0 colorIndexArray->push_back(1); // vertex 1 assigned color array element 1 colorIndexArray->push_back(2); // vertex 2 assigned color array element 2 colorIndexArray->push_back(3); // vertex 3 assigned color array element 3 colorIndexArray->push_back(0); // vertex 4 assigned color array element 0 下一步,将颜色数组和 geometry 关联起来,将上面产生的颜色索引指定给 geometry,设定绑定 模式为_PER_VERTEX。 pyramidGeometry->setColorArray(colors); pyramidGeometry->setColorIndices(colorIndexArray); pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); osg::Vec2Array* texcoords = new osg::Vec2Array(5); (*texcoords)[0].set(0.00f,0.0f); (*texcoords)[1].set(0.25f,0.0f); (*texcoords)[2].set(0.50f,0.0f); (*texcoords)[3].set(0.75f,0.0f); (*texcoords)[4].set(0.50f,1.0f); pyramidGeometry->setTexCoordArray(0,texcoords); 注:一下部分可能错误

/Declare and initialize a transform node. osg:PositionAttitudeTransform*pyramidTwoXForm new osg:PositionAttitudeTransform(); /Use the 'addChild'method of the osg:Group class to /add the transform as a child of the root node and the /pyramid node as a child of the transform. root->addChild(pyramidTwoXForm): pyramidTwoXForm->addChild(pyramidGeode); /Declare and initialize a Vec3 instance to change the /position of the tank model in the scene osg:Vec3 pyramidTwoPosition(15,0,0); pyramidTwoXForm->setPosition(pyramidTwoPosition ) 既然我们生成了一个geometry节点并将它加到了场景中,我们就可以重用这个geometry。.例如, 如果我们想让另一个pyramid在第一个的右侧l5个单位处,我们就可以在我们的scene graph中 将这个geode加到transform节点的子节点上。 最后一步,建立并进入一个仿真循环。 viewer.setUpViewer(osgProducer:Viewer:STANDARD_SETTINGS); viewer.setSceneData(root ) viewer.realize(); while(!viewer.done()) { viewer.sync(); viewer.update(); viewer.frame(); 2.使用StateSet产生有纹理的几何体 2.1本章目标 为教程1中介绍的由OpenGL基本绘制单位定义的几何体添加纹理。 2.2背景 前一节教程介绍了包含由OpenGL基本单位产生的基本形状的视景。本节讲解如何为这些形状 添加纹理。为了使代码更方便使用,我们将pyramid的代码放到一个函数中,产生geode并返回它 的指针。下面的代码来自教程1。 osg:Geode*createPyramid()

4 // Declare and initialize a transform node. osg::PositionAttitudeTransform* pyramidTwoXForm = new osg::PositionAttitudeTransform(); // Use the 'addChild' method of the osg::Group class to // add the transform as a child of the root node and the // pyramid node as a child of the transform. root->addChild(pyramidTwoXForm); pyramidTwoXForm->addChild(pyramidGeode); // Declare and initialize a Vec3 instance to change the // position of the tank model in the scene osg::Vec3 pyramidTwoPosition(15,0,0); pyramidTwoXForm->setPosition( pyramidTwoPosition ); 既然我们生成了一个 geometry 节点并将它加到了场景中,我们就可以重用这个 geometry。例如, 如果我们想让另一个 pyramid 在第一个的右侧 15 个单位处,我们就可以在我们的 scene graph 中 将这个 geode 加到 transform 节点的子节点上。 最后一步,建立并进入一个仿真循环。 viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); viewer.setSceneData( root ); viewer.realize(); while( !viewer.done() ) { viewer.sync(); viewer.update(); viewer.frame(); } 2.使用 StateSet 产生有纹理的几何体 2.1 本章目标 为教程 1 中介绍的由 OpenGL 基本绘制单位定义的几何体添加纹理。 2.2 背景 前一节教程介绍了包含由 OpenGL 基本单位产生的基本形状的视景。本节讲解如何为这些形状 添加纹理。为了使代码更方便使用,我们将 pyramid 的代码放到一个函数中,产生 geode 并返回它 的指针。下面的代码来自教程 1。 osg::Geode* createPyramid() {

osg:Geode*pyramidGeode new osg:Geode(); osg:Geometry*pyramidGeometry new osg:Geometry(); pyramidGeode->addDrawable(pyramidGeometry); //Specify the vertices: osg:Vec3Array*pyramidVertices new osg:Vec3Array: pyramidVertices->push_back(osg:Vec3(0,0,0));//front left pyramidVertices->push_back(osg:Vec3(2,0,0))://front right pyramidVertices->push_back(osg:Vec3(2,2,0));//back right pyramidVertices->push_back(osg:Vec3(0,2,0))://back left pyramidVertices->push_back(osg:Vec3(1,1,2))://peak /Associate this set of vertices with the geometry associated with the /geode we added to the scene. pyramidGeometry->setVertexArray(pyramidVertices ) /Create a QUAD primitive for the base by specifying the /vertices from our vertex list that make up this QUAD: osg:DrawElementsUInt*pyramidBase new osg:DrawElementsUInt (osg:PrimitiveSet:QUADS,0); pyramidBase->push_back(3); pyramidBase->push_back(2); pyramidBase->push_back(1); pyramidBase->push_back(0); //Add this primitive to the geometry: pyramidGeometry->addPrimitiveSet(pyramidBase); /code to create other faces goes here! //(removed to save space,see tutorial two) osg:Vec4Array*colors new osg:Vec4Array; colors->push_back(osg:Vec4(1.0f,0.Of,0.0f,1.0f));//index 0 red colors->push_back(osg:Vec4(0.Of,1.0f,0.Of,1.0f));//index 1 green colors->push_back (osg:Vec4(0.0f,0.Of,1.0f,1.0f));//index 2 blue colors->push_back(osg:Vec4(1.Of,1.0f,1.Of,1.0f));//index 3 white osg:TemplatelndexArray *colorIndexArray; colorIndexArray new osg:TemplateIndexArray; colorIndexArray->push_back(0);//vertex 0 assigned color array element 0

5 osg::Geode* pyramidGeode = new osg::Geode(); osg::Geometry* pyramidGeometry = new osg::Geometry(); pyramidGeode->addDrawable(pyramidGeometry); // Specify the vertices: osg::Vec3Array* pyramidVertices = new osg::Vec3Array; pyramidVertices->push_back( osg::Vec3(0, 0, 0) ); // front left pyramidVertices->push_back( osg::Vec3(2, 0, 0) ); // front right pyramidVertices->push_back( osg::Vec3(2, 2, 0) ); // back right pyramidVertices->push_back( osg::Vec3( 0,2, 0) ); // back left pyramidVertices->push_back( osg::Vec3( 1, 1,2) ); // peak // Associate this set of vertices with the geometry associated with the // geode we added to the scene. pyramidGeometry->setVertexArray( pyramidVertices ); // Create a QUAD primitive for the base by specifying the // vertices from our vertex list that make up this QUAD: osg::DrawElementsUInt* pyramidBase = new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0); pyramidBase->push_back(3); pyramidBase->push_back(2); pyramidBase->push_back(1); pyramidBase->push_back(0); //Add this primitive to the geometry: pyramidGeometry->addPrimitiveSet(pyramidBase); // code to create other faces goes here! // (removed to save space, see tutorial two) osg::Vec4Array* colors = new osg::Vec4Array; colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); //index 0 red colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f) ); //index 1 green colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f) ); //index 2 blue colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f) ); //index 3 white osg::TemplateIndexArray *colorIndexArray; colorIndexArray = new osg::TemplateIndexArray; colorIndexArray->push_back(0); // vertex 0 assigned color array element 0

colorIndexArray->push_back(1);//vertex 1 assigned color array element 1 colorIndexArray->push_back(2)://vertex 2 assigned color array element 2 colorIndexArray->push_back(3);//vertex 3 assigned color array element 3 colorIndexArray->push back(0);/vertex 4 assigned color array element 0 pyramidGeometry->setColorArray(colors): pyramidGeometry->setColorIndices(colorIndexArray); pyramidGeometry->setColorBinding(osg:Geometry:BIND_PER_VERTEX); /Since the mapping from vertices to texture coordinates is 1:1, /we don't need to use an index array to map vertices to texture /coordinates.We can do it directly with the 'setTexCoordArray' /method of the Geometry class. /This method takes a variable that is an array of two dimensional /vectors (osg:Vec2).This variable needs to have the same /number of elements as our Geometry has vertices.Each array element /defines the texture coordinate for the cooresponding vertex in the /vertex array. osg:Vec2Array*texcoords new osg:Vec2Array (5); (*texcoords)[0].set(0.00f,0.0f);/tex coord for vertex 0 (*texcoords)[1].set(0.25f,0.0f);//tex coord for vertex I (*texcoords))[2].set(0.50f,0.0f):/"” (*texcoords)[3].set(0.75f,0.Of);//"" (*texcoords)[4].set(0.50f,1.0f);//"" pyramidGeometry->setTexCoordArray(0,texcoords); return pyramidGeode; 2.3加载纹理,生成状态集合并将他们附加到节点上 渲染基本单位的方法是使用StateSet.。这节代码演示了怎样从文件中加载纹理,产生此纹理起 作用的一个StateSet,.并将这个StateSet附加到场景中的一个节点上。前面开始的代码和上一节 教程中的一样,初始化一个viewer并建立有一个pyramid的场景。 int main() { osgProducer:Viewer viewer; /Declare a group to act as root node of a scene: osg:Group*root new osg:Group(); 6

6 colorIndexArray->push_back(1); // vertex 1 assigned color array element 1 colorIndexArray->push_back(2); // vertex 2 assigned color array element 2 colorIndexArray->push_back(3); // vertex 3 assigned color array element 3 colorIndexArray->push_back(0); // vertex 4 assigned color array element 0 pyramidGeometry->setColorArray(colors); pyramidGeometry->setColorIndices(colorIndexArray); pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); // Since the mapping from vertices to texture coordinates is 1:1, // we don't need to use an index array to map vertices to texture // coordinates. We can do it directly with the 'setTexCoordArray' // method of the Geometry class. // This method takes a variable that is an array of two dimensional // vectors (osg::Vec2). This variable needs to have the same // number of elements as our Geometry has vertices. Each array element // defines the texture coordinate for the cooresponding vertex in the // vertex array. osg::Vec2Array* texcoords = new osg::Vec2Array(5); (*texcoords)[0].set(0.00f,0.0f); // tex coord for vertex 0 (*texcoords)[1].set(0.25f,0.0f); // tex coord for vertex 1 (*texcoords)[2].set(0.50f,0.0f); // "" (*texcoords)[3].set(0.75f,0.0f); // "" (*texcoords)[4].set(0.50f,1.0f); // "" pyramidGeometry->setTexCoordArray(0,texcoords); return pyramidGeode; } 2.3 加载纹理,生成状态集合并将他们附加到节点上 渲染基本单位的方法是使用 StateSet。这节代码演示了怎样从文件中加载纹理,产生此纹理起 作用的一个 StateSet,并将这个 StateSet 附加到场景中的一个节点上。前面开始的代码和上一节 教程中的一样,初始化一个 viewer 并建立有一个 pyramid 的场景。 int main() { osgProducer::Viewer viewer; // Declare a group to act as root node of a scene: osg::Group* root = new osg::Group();

点击下载完整版文档(DOC)VIP每日下载上限内不扣除下载券和下载次数;
按次数下载不扣除下载券;
24小时内重复下载只扣除一次;
顺序:VIP每日次数-->可用次数-->下载券;
共49页,可试读17页,点击继续阅读 ↓↓
相关文档

关于我们|帮助中心|下载说明|相关软件|意见反馈|联系我们

Copyright © 2008-现在 cucdc.com 高等教育资讯网 版权所有