APP下载

OpensSceneGraph程序设计的应用

2020-11-26黄聪

电子技术与软件工程 2020年15期
关键词:指针开发者纹理

黄聪

(咸宁职业技术学院 湖北省咸宁市 437100)

1 引言

OpensSceneGraph(OSG)是一个跨平台开源场景图形程序开发接口。它作为中间件为应用软件提供了各种高级渲染特性,IO,以及空间结构组织函数。它封装并提供许多提升程序运行性能的算法,利用显示列表、OpenGL 状态排序、着色语言、LOD 等方法提高效率,提供了绝大多数主流数据格式的直接数据接口(包括图片、三维模型,以及字体等),同时支持脚本语言系统Python、Tcl、Lua 等。

2 程序设计分析

2.1 内存管理

当应用程序不再使用场景图形时,OSG 使用内存引用计数器(referencecounted memory)来自动释放场景图形节点,OSG的内存管理机制将在最后一个指向根节点的指针被释放时,释放整个场景图形。这种内存引用计数机制包含以下两个组件:基类osg::Referenced 和智能指针模板类ref_ptr<>。当创建任何继承自Referenced 的节点时,程序切不可直接释放其内存空间,也不要用标准C++指针变量长时间保存继承自Referenced 类的对象指针,否则编译时会提示错误信息。在osg::Reference 类成员函数中,有两个成员函数ref()和unref(),二者主要用来控制内存计数,程序不要随意改变内存计数器的值。运算符dynamic_cast 的主要作用是将基类的指针或者引用安全地转换为派生类的指针或者引用,然后用派生类的指针或者引用调用非虚函数,需要注意的是,在类层次间进行转换时,基类型至少含有虚函数才能进行这种转换。开发者在编写代码时为避免出现内存泄漏和指针悬挂问题,应编写清洁的代码。

2.2 场景管理

场景管理是OSG 渲染引擎的核心部分,OSG 利用包围体层次包围体层次(Bounding Volume Hierarchy,BVH)来实现场景图形的管理。通过综合使用包围球(Bounding Sphere)和包围盒(Bounding Box)这两种形式来尽可能达到最佳的场景组织和访问性能。当有节点树中某节点发生变化时,需要重新计算该节点包围球的大小和位置,一直递归到根节点,从而维护整个BVH 树。场景图形采用一种自顶向下的、分层的树状数据结构来组织空间数据集,场景图形树的顶部是一个根节点,从根节点向下延伸,各个组节点中包含几何信息和渲染状态信息,各个叶节点包含了构成场景中物体的实际几何信息。场景树包含的不同类型节点可以执行各种不同的功能,如开关节点可设置子节点是否可用;细节层次节点可根据观察者的距离调用不同的子节点;变换节点可改变子节点几何体的坐标变换状态。简单的场景可能只有一个Camera,复杂的场景可能有多个Camera,不同的Camara 从不同的角度看向同一个场景时,可能看到不同的场景,在渲染的时候,通过遍历Camera,已完成渲染。不同的节点实现不同的功能,开发者应根据需要灵活应用,同时选择合适的角度以观察主场景。

2.3 访问器机制

OSG 中的osg::NodeVisitor 是对访问器模式思想的具体实现,访问器的设计允许应用程序将某个特定节点的指定函数应用到场景中的所有节点。通常的做法是继承自osg::NodeVisitor 这个虚基类,重载apply()方法以获取各个节点的属性或者修改节点的属性,在程序中调用accept()方法关联需要访问的节点,并启动访问器进行遍历。这种做法主要适用于一个对象结构包含很多类对象,这些类对象有不同的接口,而想对它们实施一些依赖于其具体类的操作。如果对象结构类经常改变,那么可能在类中定义这些新的操作比较好。根据功能需要,可设置顶点访问器,纹理访问器,节点访问器,编写的访问器重载基类的apply()函数以实现相应功能,例如要查找指定的节点时,判断某个节点名称是否与要查找的节点名称一样,将找到的节点添加到自己的节点列表或者从节点列表删除。

2.4 渲染管理

OSG 采用状态机机制osg::StateSet 来跟踪所用的渲染状态,被状态机管理的渲染状态有:光照lights、材质materials、纹理textures 等,它主要管理渲染属性和渲染模式。将一个场景图形关联到一个实例化的osgViewer::Viewer 对象进行渲染。因为Viewer类的osg::Camera 对象管理模型-视图矩阵,可通过控制Camera对象来改变每一帧的视口显示或者设置清屏颜色。在动态修改场景图形时应避免与拣选及绘制线程发生冲突。OSG 支持绝大部分OpenGL 固定功能管道(fixed function pipeline)渲染,如Alpha 检验,剪切平面,深度和模板检验,雾效,点和线的光栅化等。在程序中设置osg::StateSet 渲染状态,但应使关联到场景图形的StateSet 最小化,减少一次场景图形遍历中所耗费的工作量,从而减少内存的占用。默认情况下,所有的节点渲染状态都继承父节点的渲染状态,除非开发者该表节点的渲染状态或者继承模式。OSG 的渲染归纳起来包括三个阶段:用户阶段、更新数据阶段、场景的管理阶段,最终利用renderingTraversals()函数完成场景的拣选和绘制工作。

2.5 纹理映射

纹理映射即纹理贴图,使用纹理映射可以大大提高三维物体的真实感,达到良好的显示效果。OSG 全面支持OpenGL 的纹理映射机制,OSG 加载纹理并把纹理送达GUP 的过程中,对纹理进行了缩放和归一化处理。对纹理的操作主要包括一维纹理、二维纹理、三维纹理、多重纹理、Mipmap 纹理和压缩纹理等。二维纹理映射中纹理坐标与几何体的顶点坐标一一对应。多重纹理映射是多个二维纹理映射的叠加,对于不同的纹理属性对象需要指定不同的纹理单元及纹理坐标,否则不会启用该纹理单位或者该纹理单元会被覆盖。Mipmap 纹理映射需要指定各层的纹理图像数据,用以避免图像缩放时出现的抖动或者闪烁现象,同时减少不必要的渲染负担。程序员除了可以使用TextureRectangle 纹理映射,还可以自动生成纹理坐标,以实现使用纹理贴图生成模型的轮廓线或者光泽模型对任意环境的反射。

2.6 回调机制

OSG 的回调机制主要有如下三种:osg::Node、osg::Drawable、osg::Camera。osg::Node 在OSG 执行更新和拣选遍历时进行回调;osg::Drawable 在拣选和绘制遍历时进行回调;osg::Camera在更新遍历时进行回调。目前经常开发者经常使用节点回调(NodeCallback)和事件回调(EventCallback)。使用节点回调需重载operator()方法,以实现场景的动态更新。当交互事件触发,如操作键盘、鼠标、改变窗口或者点选场景中的某节点,事件回调不仅要重载operator()方法,还需创建事件访问器并重载handle()方法,将回调实例关联所需对象,如setUpdateCallback(),setEvent Callback(),setCullCallback(),setReadFileCallback()等。所有的事件均在osgViewer::Viewer::eventTraversal 中进行,它将每个事件都发送到_eventHandlers 中的每个事件处理器中,经过层层过滤,最终的操作由osgGA::GUIEventHandler 进行处理。

2.7 独立功能

OSG 使用一些工具类来实现一些相互独立的功能,例如:osgParticle 粒子系统、osgText 文字处理与显示、osgShadow 阴影、osgFX 扩展库、osgAL 三维立体声音等。osgParticle 采用Billboard与色彩融合技术,生成非常真实的粒子效果。osgText 有第三方插件FreeType 支持,用很小的点产生良好的输出,显示高质量的文字。osgShadow 用来控制渲染实时阴影,渲染的时候要标记出阴影投影对象和阴影接收对象。osgFX 扩展库是OSG 的附加库,它定义了一系列定义好的特殊效果,这些效果可以添加到OSG 的节点中,如异性光照特效、凹凸贴图特效、卡通渲染特效、刻线特效、立方图镜面高光特效等。osgAL 提供三维位置音效,它支持的声源的最大数量由电脑的显卡决定,但最多不应超过32 个声源,否则程序会出错。

3 平台实现

OSG 具有跨平台的特性,可运行在所有Windows、Linux、IOS、Android 等操作系统平台,支持嵌入式设备。此外,OSG 可以运行在多核的CPU 和GPU 上,因为它对OpenGL 显示列表、纹理单元、绘制遍历等过程实施了保护措施,以实现异构模式下的混合编程,可以通过osgViewer 配置当前OSG 应用程序的线程模型,渲染管线的不同阶段可以单独作为一个线程也可以在一个线程中串行执行。它还支持各种UI,如Qt、MFC、SDL、GLUT、Wxwidget 等,分析研究Qt 的工作原理与信号槽消息机制,可编码实现基于OSG与Qt 的应用程序。

4 应用领域

OSG 在三维应用程序的开发中扮演着重要的角色,广泛应用于地理信息系统(GIS),计算机辅助设计(CAD),建模和数字内容创作(DCC),数据库开发,可视化(飞机、船舶、车辆等仿真)、三维建模、虚拟现实(VR)、教育、动画和游戏等领域。

5 总结

OpenSceneGraph 作为一种优秀的开源三维程序渲染引擎,它完全是由标准C++程序和OpenGL 编写,充分利用STL 和设计模式,让开发者避免复杂的底层图形实现和优化,为三维图形应用程序的开发提供了很多方便,同时,它在性能、可扩展性、可移植性等方面具有极大优势,能更加快速创建高性能、跨平台的交互式图形程序,广泛应用于三维可视化仿真、游戏、虚拟现实等高性能图形应用程序设计中。

猜你喜欢

指针开发者纹理
使用纹理叠加添加艺术画特效
TEXTURE ON TEXTURE质地上的纹理
消除凹凸纹理有妙招!
iOS开发者调查
iOS开发者调查
基于改进Hough变换和BP网络的指针仪表识别
栝楼产业开发者谢献忠
ARM Cortex—MO/MO+单片机的指针变量替换方法