Osg 源代码结构和主要的类


OSG 包含了一系列的开源图形库,主要为图形图像应用程序的开发提供场景管理和图形渲染优化的功能。它使用可移植的ANSI C++编写,并使用已成为工业标准的OpenGL 底层渲染API。因此, OSG 具备跨平台性,可以运行在Windows,Mac OS X 和大多数类型的UNIX 和Linux 操作系统上。大部分的 OSG操作可以独立于本地视窗系统。但是 OSG 也包含了针对某些视窗系统特有功能的支持 代码,例如PBuffers。 OSG 是公开源 代码的,它的用户许可方式为修改过的GNU 宽通用公共许可证(GNU Lesser General Public License,LGPL)。 OSG 采用开源形式的共享方案具备了诸多益处:
● 提高品质: OSGOSG community 的诸多成员反复进行检查、测试和改善。直接参与 OSG 1.2 的开发人员已经超过了200 人。
● 提高程序质量:要编写高质量的程序,开发者需要十分了解自己所用的开发包。如果这个开发包不开放源 代码,与它相关的开发信息就被封闭起来,用户只能借助开发商的文档和客户支持来获得开发信息。开放源 代码使得程序员可以检查和调试所用开发包的源 代码,充分了解 代码内部信息。
● 减少费用:开源意味着免费,除了一开始购买软件所需的费用
● 没有知识产权问题:对于开源且易于所有人阅读的 代码而言,不存在侵
犯软件专利的可能性。
1.6.1 设计和体系
OSG 的设计兼顾系统的可移植性和可扩展性。因此, OSG 适用于多种硬件平台,并可在多种不同的图形硬件上进行高效的、实时的渲染。 OSG 具备灵活、可扩展的系统特性,使其能自适应不同时期的设计和应用需求。综上所述, OSG已具备了满足各类客户的、不断增长的需求的能力。
为达到以上设计目标理念, OSG 采用了以下设计理念和工具进行系统的设计和构建:
● ANSI 标准C++;
● C++标准模板库(STL);
● 设计模式(Design patterns,Gamma95)。
这些工具使得程序员可以在自己喜好的平台上使用 OSG 进行开发,并且依据用户指定的平台对 OSG 进行配置。
1.6.2 命名习惯
以下列举了 OSG代码中的一些命名习惯。这些命名习惯可能不会被严格遵守,例如许多由第三方开发的 OSG 插件中就有违反命名习惯的情况。
● 命名空间: OSG 的域名空间使用小写字母开头,然后可以使用大写字母以避免混淆。例如, osg,osgSim,osgFX 等。
● 类: OSG 的类名以大写字母开头,如果类的名称是多个单词的组合,此后每个单词的首字母大写。例如,MatrixTransform,NodeVisitor,Optimizer。
● 类方法: OSG 类的方法名使用小写字母开头,如果方法的名称是多个单词的组合,此后每个单词的首字母大写。例如,addDrawable() ,。getNumChildren(),setAttributeAndModes()。
● 类成员变量:类的成员变量命名与方法命名的方式相同。
● 模板: OSG 模板的命名用小写字母,多个单词之间使用下划线分隔。例如,ref_ptr<>,graph_array<>,observer_ptr<>。
● 静态量:静态变量和函数的名称使用s_开头,此后的命名与类成员变量及函数的命名方法相同。例如,s_applicationUsage,s_ArrayNames()。
● 全局量: 全局类的实例命名用g_ 开头。例如, g_NotifyLevel ,g_readerWriter_BMP_Proxy。
1.6.3 组件
OSG 运行时文件由一系列动态链接库(或共享对象)和可执行文件组成。这些链接库可分为以下五大类:
OSG 核心库。它提供了基本的场景图形和渲染功能,以及3D 图形程序所需的某些特定功能实现。
● NodeKits。它扩展了核心 OSG 场景图形节点类的功能,以提供高级节点类型和渲染特效。
OSG 插件。其中包括了2D 图像和3D 模型文件的读写功能库。
● 互操作库。它使得 OSG 易于与其它开发环境集成,例如脚本语言Python和Lua。
● 不断扩展中的程序和示例集。它提供了实用的功能函数和正确使用 OSG的例子。
图1-9 表示了 OSG 的体系 结构图。下面的章节将更进一步地讨论 OSG 的各个功能模块。
图1-9 OSG 体系 结构
OSG
核心库提供了应用程序和NodeKits 所需的功能模块。而 OSG 核心库和NodeKits 一同组成了 OSG 的API。 OSG 核心库中的osgDB 则通过对 OSG 插件的管理,为用户提供了2D 和3D 文件I/O 的接口。


OSG 核心库
   OSG
核心库提供了用于场景图形操作的核心场景图形功能、类和方法;开发3D 图形程序所需的某些特定功能函数和编程接口;以及2D 和3D 文件I/O 的 OSG 插件入口。 OSG 核心库包含了以下四个链接库:
osg 库: osg 库包含了用于构建场景图形的场景图形节点类,用作向量和矩阵运算的类,几何体类,以及用于描述和管理渲染状态的类。 osg 库中还包括3D 图形程序所需的典型功能类,例如命令行参数解析,动画路径管理,以及错误和警告信息类。
● osgUtil 库: osg 工具库包括的类和函数,可以用于场景图形及其内容的操作,场景图形数据统计和优化,以及渲染器的创建。它还包括了几何操作的类,例如Delaunay 三角面片化(Delaunay triangulation),三角面片条带化(triangle stripification),纹理坐标生成等。
● osgDB 库:此链接库包括了建立和渲染3D 数据库的类与函数。其中包括用于2D 和3D 文件读写的 OSG 插件类的注册表,以及用于访问这些插件的特定功能类。osgDB 数据库分页机(database pager)可以支持大型数据段的动态读入和卸载。
● osgViewer 库:这个库是 OSG 的2.0 版本新增的,它包含了场景中视口及可视化内容的管理类。osgViewer 已将 OSG 集成到多种多样的视窗系统中。
    OSG 的2.0 版本还包括了用于改写界面事件的osgGA 库。但不久以后 OSG将会放弃独立的osgGA 链接库,并将其所包含的功能集成到osgViewer 中去,而不再作为一个独立的库存在。
在以下部分中,我们将更进一步地讨论这四个核心的链接库。
osg 链接库
命名空间: osg
头文件:<OSG_DIR>/include/osg
Windows 库文件:osg.dll,osg.lib
Linux 和Mac OS X 库文件:libosg.lib

    osg 库是OpenSceneGraph 的核心部分。它定义了组成场景图形的核心节点,以及帮助用户进行场景图形管理和程序开发的一些附加类。下面将对其中的一些类作简要的叙述。本书的第二章将更为详细地介绍它们,并指导你如何在程序中使用这些类。
场景图形类
    场景图形类用于辅助场景图形的构建。 OSG 中所有的场景图形类都继承自 osg::Node。从概念上讲,根节点,组节点和叶节点是不同的节点类型。在 OSG中,它们都源自于 osg::Node,但是特定的类会提供不同的场景图形功能。此外, OSG 中的根节点并不是特定的节点类型,它仅仅是一个没有父类的 osg::Node 类。
● Node:Node 类是场景图形中所有节点的基类。它包含了用于场景图形遍历、拣选、程序回调,以及状态管理的方法。
● Group:Group 类是所有可分支节点的基类。它是场景图形空间组织 结构的关键类。
● Geode:Geode 类(即Geometry Node)相当于 OSG 中的叶节点。它没有子节点,但是包含了 osg::Drawable 对象,而 osg::Drawable 对象中存放了将要被渲染的几何体。
● LOD:LOD 类根据观察点与图像子节点的距离选择显示子节点。通常使用它来创建场景中物体的多个显示层级。
● MatrixTransform:MatrixTransform 类包含了用于实施子节点几何体空间转换的矩阵,以实现场景对象的旋转、平移、缩放、倾斜、映射等操作。
● Switch:Switch 类用布尔掩板来允许或禁止子节点的运作。

   以上内容并未涵盖所有的OSG 节点类型。其它的节点类型还有很多,如Sequence,PositionAttitudeTransform 等。你可以参考osg 库的头文件来了解有关它们的信息。

几何体类
   Geode 类是OSG 的叶节点,它包含了渲染用的几何数据。使用以下列出的类可以实现Geode 中几何数据的存储。
● Drawable:Drawable 类是用于存储几何数据信息的基类,Geode 维护了一个Drawable 的列表。Drawable 是纯虚类,无法直接实例化。用户必须实例化其派生类,如Geometry,或者ShapeDrawable(允许用户程序绘制预定义的几何形状,如球体、圆锥体和长方体)。
● Geometry:Geometry 类与PrimitiveSet 类相关联,实现了对OpenGL 顶点数组功能的高级封装。Geometry 保存顶点数组的数据,纹理坐标,颜色,以及法线数组。
● PrimitiveSet:PrimitiveSet 类提供了OpenGL 顶点数组绘图命令的高层次支持。用户可以从相关的Geometry 类中取得保存的数据,再使用这个类来指定要绘制的几何体数据的类型。
● Vector 类(Vec2,Vec3 等):OSG 提供了预定义好的二维,三维和四维元素向量,支持float 或者double 类型。使用这些向量来指定顶点、颜色、法线和纹理坐标的信息。
● Array 类(Vec2Array,Vec3Array 等):OSG 定义了一些常用的数组类型,如用于贴图纹理坐标的Vec2Array。指定顶点数组数据时,程序首先将几何数据保存到这些数组中,然后传递至Geometry 类对象。

   也许上面的叙述有些混乱,不过可以总结为这样几条:Geode 类是场景图形的叶节点,其中保存了Drawable 类;Geometry 类(仅Drawable 类型)保存了顶点数组数据和及其顶点数组的渲染指令;数据的组成为向量数组。第二章“建立场景图形”将涵盖上述所有的内容并作详细讲解。

状态管理类
   OSG
提供了一种机制,用以保存场景图形所需的OpenGL 渲染状态。在拣选遍历中,同一状态的几何体将被组合集中到一起以使状态的改变呈最小化。在绘制遍历中,状态管理代码将记录当前状态的历史轨迹,以清除冗余的渲染状态变更。和其它场景图形系统不同,OSG 允许状态与任何场景图形节点相关联,在一次遍历中,状态将呈现出某种继承关系的。
● 状态集合(StateSet):OSG 在StateSet 类中保存一组定义状态数据(模式和属性)。场景图形中的任何osg::Node 都可以与一个StateSet 相关联。
● 模式(Modes):与OpenGL 的函数glEnable()和glDisable()相似,模式用于打开或关闭OpenGL 固定功能(fixed-function)的渲染管道,例如灯光,混合和雾效。方法osg::StateSet::setMode()在StateSet 中保存一个模式信息。
● 属性(Attributes):应用程序使用属性来指定状态参数,例如混和函数,材质属性,雾颜色等。方法osg::StateSet::setAttribute()在StateSet 中保存属性信息。
● 纹理模式和属性:纹理模式和属性可应用在OpenGL 多重纹理的某个指定纹理单元上。应用程序必须在设定纹理模式和属性时提供纹理单元的信息,注意,和OpenGL 不同,OSG 不存在缺省的纹理单元。StateSet类的方法setTextureMode()和setTextureAttribute()用于设定状态参量以及纹理单元信息。
● 继承标志:OSG 提供了一些标志量,用于控制场景图形遍历中的状态值。缺省情况下,子节点中的状态集合将重载父节点的状态集合,但是也可以强制父节点的状态重载子节点的状态,或者指定子节点的状态受到保护而不会被其父节点重载。

   上述状态系统已经被证明是非常灵活的。所有新添加到OpenGL 规范中的状态数据,包括最新的OpenGL 着色语言(Shading Language,[Rost06]),都可以顺利地嵌入到OSG 状态系统中。

其它实用类
   除上述类外,osg 链接库还包括了一些实用的类和工具。其中一些涉及到OSG 的内存引用计数策略(reference-counted memory scheme),这种策略可以通过清理不再引用的内存以避免内存泄露。第二章“建立场景图形”将详细讲解内存引用计数的内容。
● Referenced:Referenced 类是所有场景图形节点和OSG 的许多其它对象的基类。它实现了一个用于跟踪内存使用情况的引用计数(referencecount)。如果某个继承自Referenced 的对象,其引用计数的数值到达0,那么系统将自动调用其析构函数并清理为此对象分配的内存。
● ref_ptr<>:模板类ref_ptr<>为其模板内容定义了一个智能指针,模板内容必须继承自Referenced 类(或提供一个与之相同的、能实现引用计数的接口)。当对象的地址分配给ref_ptr<>时,对象的引用计数将自动增加。同样,清除或者删去ref_ptr 时,对象的引用计数将自动减少。
● Object:纯虚类Object 是OSG 中一切需要I/O 支持,拷贝和引用计数的对象的基类。所有的节点类,以及某些OSG 对象均派生自Object 类。
● Notify:osg 库提供了一系列控制调试,警告和错误输出的函数。用户可以通过指定一个来自NotifySeverity 枚举量的数值,设定输出的信息量。OSG 中的大部分代码模块执行时都会显示相关的信息。
   osg 链接库还包括了一些本节没有提及的类。你可以参考osg 库的源代码和头文件,以了解更多的类及其特性。

osgDB 链接库
命名空间:osgDB
头文件:<OSG_DIR>/include/osgDB
Windows 库文件:osgDB.dll,osgDB.lib
Linux 和Mac OS X 库文件:libosgDB.lib

    osgDB 库允许用户程序加载、使用和写入3D 数据库。它采用插件管理的架构,可以支持大量常见的2D 图形和3D 模型文件格式。osgDB 负责维护插件的信息注册表,并负责检查将要被载入的OSG 插件接口的合法性。
    OSG 可以支持自己的文件格式。.osg 文件是对场景图形的一种无格式ASCII码文本描述,而.osga 文件是一组.osg 文件的有序集合。osgDB 库包含了以上文件格式的支持代码。(另外,OSG 还支持一种二进制的.ive 格式。)由于大型的3D 地型数据库通常是多段数据块的组合体,。因此,应用程序
从文件中读取各部分数据库信息时,需要在不干扰当前渲染的前提下以后台线程的方式进行。osgDB::DatabasePager 提供了这样的功能。
osgViewer 链接库
名空间:osgViewer
头文件:<OSG_DIR>/include/osgViewer
Windows 库文件:osgViewer.dll,osgViewer.lib
Linux 和Mac OS X 库文件:libosgViewer.lib

    osgViewer 库定义了一些视口类,因而可以将OSG 集成到许多视窗设计工具中,包括AGL/CGL,FLTK,Fox,MFC,Qt,SDL,Win32,WxWindows,以及X11。这些视口类支持单窗口/单视口的程序,也支持使用多个视口和渲染器面的多线程程序。每个视口类都可以提供对摄像机运动,事件处理,以及
osgDB::DatabasePager 的支持。osgViewer 库包含了以下三个可能用到的视口类。
● SimpleViewer:SimpleViewer 类负责管理单一场景图形中的单一视口。使用SimpleViewer 时,应用程序必须创建一个窗口并设置当前的图形上下文(graphics context)。
● Viewer:Viewer 类用于管理多个同步摄像机,他们将从多个方向渲染单一的视口。根据底层图形系统的能力,Viewer 可以创建一个或多个自己的窗口以及图形上下文,因此使用单一视口的程序也可以在单显示或者多显示的系统上运行。
● CompositeViewer:CompositeViewer 类支持同一场景的多个视口,也支持不同场景的多个摄像机。如果指定各个视口的渲染顺序,用户就可以将某一次渲染的结果传递给别的视口。CompositeViewer 可以用来创建抬头数字显示(HUD),预渲染纹理(prerender textures),也可以用于在单一视口中显示多个视图。
osgViewer 库还包括一些额外的类,用以支持显示统计,窗口提取和场景的处理工作。

NodeKits
   NodeKits 扩展了Nodes,Drawables 和StateAttributes 的概念,也可以看作是OSG 内核中osg 库的一种扩展。NodeKits 的意义远大于对OSG 类的继承,事实上它还能够提供对.osg 的封装(一种支持对.osg 文件进行读写的OSG 插件)。总之,NodeKit 由两部分组成:NodeKit 本身,以及针对.osg 的封装插件库。OSG 2.0版本包含有六种NodeKits。
● osgFX 库:此类NodeKit 提供了额外的场景图形节点,以便于特效的渲染,例如异向光照(anisotropic lighting),凹凸贴图,卡通着色等。
● osgParticle 库:此类NodeKit 提供了基于粒子的渲染特效,如爆炸、火焰、烟雾等。
● osgSim 库:此类NodeKit 提供了仿真系统中以及渲染OpenFlight 数据库所需的特殊渲染功能,例如地形高程图,光点节点,DOF 变换节点等。
● osgText 库:此类NodeKit 提供了向场景中添加文字的得力工具,可以完全支持TrueType 字体。
● osgTerrain 库:此类NodeKit 提供了渲染高度场数据的能力。
● osgShadow 库:此类NodeKit 提供了支持阴影渲染的框架结构
如果要详细描述OSG NodeKits 的所有功能,那将超出本书所许可的范围。2.6 节“NodeKits 与osgText”将介绍osgText 的基本用法,而你在学习第二章里osgText 相关内容的同时,一定也会对其它NodeKits 的进一步探索以及使用产生浓厚兴趣。

OSG 插件
   OSG
的核心库提供了针对多种2D 图形和3D 模型文件格式的I/O 支持。osgDB::Registry 可以自动管理插件链接库。只要提供的插件确实可用,Registry就可以找到并使用它,应用程序只需调用相应的函数来读取和写入数据文件即可。

   osg 库允许用户程序采用“节点到节点”(node-by-node)的方式直接建立场景图形。相反的,OSG 插件允许用户程序仅仅通过编写几行代码就能够从磁盘中调用整个场景图形,或者调用部分的场景图形,然后应用程序可以将其列入整个场景图形系统中去。
   OSG 的2.0 版本支持大量常用的2D 图形文件格式, 包括.bmp,.dds,.gif,.jpeg,.pic,.png,.rgb,.tga 和.tiff。OSG 还支持用于读取电影文件的QuickTime 插件,并有专门的插件用于读取FreeType 类型的字体。OSG 广泛支持各种3D 模型文件格式,其中包括3D Studio Max(.3ds),AliasWavefront(.obj),Carbon Graphics’ Geo(.geo),Collada(.dae),ESRI Shapefile(.shp),OpenFlight(.flt),Quake(.md2)和Terrex TerraPage(.txp)等常见格式。
   除上述标准格式以外,OSG 还定义了自身的文件格式。其中,.osg 格式是场景图形的另一种ASCII 文本描述格式,用户可以使用文本编辑器对其进行编辑和修改;而.ive 格式则是一种二进制格式,经过优化之后它更适合于迅速读取。
   除2D 图形和3D 模型文件以外,OSG 插件还支持对压缩文件和文件集的I/O操作,OSG 目前支持的压缩文件格式有常见的.tgz 和.zip,以及OSG 特有的.osga格式。
   此外,OSG 还包含了一组名为“PseudoLoader”的插件,以提供除简单文件读取之外更多的功能。
● 缩放、旋转和平移:此类PseudoLoader 读取文件并在已读入场景图形根节点上添加一个Transform 节点,并指定放缩、旋转和平移属性的值以配置Transform。
● 图标:图标类PseudoLoader 允许在已读入3D 场景之上显示HUD(抬头显示)样式的图片文件。有关在用户程序中使用OSG 插件的方法,第2.5 节“文件I/O”将提供更多信息。

互操作性
   用户可以在任何支持C++库链接的编程环境中使用OSG。为了确保OSG 可以在更多环境中运行,OSG 提供了一个语言无关的、可供运行时访问的接口。
   osgIntrospection 库允许用户软件使用反射式和自省式的编程范式与OSG 进行交互。应用程序或其它软件可以使用osgIntrospection 库和方法迭代OSG 的类型,枚举量和方法,并且无需了解OSG 编译和链接时的具体过程,即可调用这些方法。
   Smalltalk 和Objective-C 等语言包括了内建的反射式和自省式支持,但使用C++的软件开发人员通常无法运用这些特性,因为C++并未保留必要的元数据(metadata)。为了弥补C++的这一不足,OSG 提供了一系列自动生成的、从OSG代码创建的封装库,用户程序不需要与这些OSG 的封装库直接交互,它们将完全由osgIntrospection 进行管理。
   作为osgIntrospection 及其封装的结果,许多语言如Java,Tcl,Lua 和Python,都可以与OSG 进行交互。如果要详细了解OSG 的语言互操作性及代码封装,请访问OSG 维基网站[OSGWiki],Community 页,并选择LanguageWrappers。

程序与示例
   OSG
发行版包含了五个常用的OSG 工具程序,它们对于调试和其它基于OSG 的软件开发均十分有益。
● osgarchive:这个程序用于向.osga 文件包中添加新的文件。也可以用这个程序实现包的分解和列表。
● osgconv:这个程序用于转换文件格式。尤其有用的是,它可以将任意文件格式转换为经过优化的.ive 格式。
● osgdem:这个程序用于将高程图等高度数据及图像数据转换为分页的地形数据库。
● osgversion:这个程序将当前OSG 版本以及一些记录了OSG代码改动情况和贡献者信息送入std::cout。
● osgviewer:这是一个灵活而强大的OSG 场景及模型浏览器。1.3 节“运行osgviewer”详细说明了这个程序的实用方法。
   OSG 发行版还包含了一些展现API 功能的示例程序。例程源代码同时也展现了OSG 程序在其开发过程中所应用的大量编程理念和实用技巧。

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值