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);