若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/95042433
目录
前言
建立场景前需知道的内存管理
连锁释放
连锁释放依赖的组件
相关类
Referenced类
ret_ptr< >模板类
内存管理示例
示例1
示例2
示例3
示例4
总结
参考资料
《OSG开发笔记(一):OSG介绍、编译》
《OSG开发笔记(二):OSG帮助文档编译》
《OSG开发笔记(三):OSG使用osgQt嵌入Qt应用程序》
《OSG开发笔记(四):OSG不使用osgQt重写类嵌入Qt应用程序》:
《OSG开发笔记(五):OSG场景理解与基础类概述》
《OSG开发笔记(六):OSG内存管理》
《OSG开发笔记(七):OSG复现OpenGL入门示例和OSG坐标系》
《OSG开发笔记(八):OSG模型文件存储与读取》
《OSG开发笔记(九):OSG模型的基本操作之添加/删除、显示/隐藏、开关节点开/关》:
《OSG开发笔记(十):OSG模型的变换之平移、旋转和缩放》
《OSG开发笔记(十一):OSG渲染状态与2D纹理映射》
《OSG开发笔记(十二):OSG基本几何图形、内置几何类型》
《OSG开发笔记(十三):OSG三维纹理映射(体渲染)》
《OSG开发笔记(十四):OSG交互》
《OSG开发笔记(十五):OSG光照》
《OSG开发笔记(十六):OSG视口、相机和视点》
《OSG开发笔记(十七):OSG中的相机移动》
《OSG开发笔记(十八):OSG鼠标拾取pick、拽托球体以及多光源》
《OSG开发笔记(十九):OSG文字显示》
《OSG开发笔记(二十):OSG使用HUD显示文字》
《OSG开发笔记(二十一):OSG使用HUD绘制图形以及纹理混合模式》
《OSG开发笔记(二十二):OSG场景背景》
《OSG开发笔记(二十三):Qt使用QOpenGLWidget渲染OSG和地球仪》
《OSG开发笔记(二十四):OSG漫游之平移、转向和低抬头》
《OSG开发笔记(二十五):OSG漫游之CS移动、碰撞检测与跳跃》
《OSG开发笔记(二十六):OSG漫游之上下楼梯》
《OSG开发笔记(二十七):OSG路径漫游之录制播放固定路径动画》
《OSG开发笔记(二十八):OSG模型固定路径动画》
持续补充中…
前篇介绍了类,在开发前还需要知道osg强大的内存管理功能。
在开始建立场景图形之前,你需要对 OSG 场景图形节点和数据所使用的内存管理机制有所了解。对这一概念的掌握将有助于编写清洁的代码,并避免出现悬挂指针和内存泄露。
当应用程序不再使用场景图形时,每个节点所使用的内存需要释放以避免内存泄露。如果要编写代码遍历整个场景图形,并依次删除所有的节点及其数据,那么这项工作将是巨大且容易出错的。
OSG 提供了一种自动的“废弃物”收集系统,它使用一种名为内存引用计数器(referencecounted memory)的方式工作。所有的 OSG 场景图形节点均采用引用计数(reference count)的方式,当引用计数值减为 0 时,此对象将被自动释放。其结果是,删除如图 2-1 所示的场景图形时,程序只需要简单地释放指向根节点的指针。这一动作将引发连锁的效果,将场景图形中的所有节点和数据逐一释放。
OSG 的“废弃物”收集系统有以下两个组件:
如果程序要保存一个继承自Referenced的对象的指针,那么将指针保存在ref_ptr< >中要好过使用标准 C++指针变量。如果代码中可以始终遵循这一原则,那么当最后一个引用对象的ref_ptr< >被弃用时,对象所占用的内存将自动释放。当你创建任何继承自 Referenced 的场景图形节点或数据时, 你的应用程序不可以直接释放其内存空间。除了极少数例外,几乎所有的Referenced派生类都声明了保护析构函数。这样可以保证,继承自Referenced的对象只能够通过减少引用计数器到 0 的方式来释放其内存。
Referenced 类(命名空间:osg)实现了对内存区段的引用计数器功能。所有的 OSG 节点和场景图形数据,包括状态信息,顶点数组,法线,以及纹理坐标,均派生自 Referenced 类。因此,所有的 OSG 场景图形均可以进行内存引用计数。
Referenced 类包括了三个主要组成部分:
总体上来说,用户的代码基本上不需要直接调用 ref()和 unref()函数,只要使用ref_ptr<>进行处理即可。
ref_ptr<>(命名空间: osg)用于实现一个指向 Referenced 对象的智能指针,并对其引用计数器进行管理。当最后一个引用 Referenced 对象的 ref_ptr<>失去作用时,对象将确保被释放。 ref_ptr<>简化了场景图形内存释放的工作,并保证当错误的调用堆栈展开时,对象也可以被正确释放。ref_ptr<>模板类包括以下三个主要的组成部分:
ref_ptr< >变量的引用计数值减少的情形有这样两种:ref_ptr< >被释放(在类的析构函数里执行减一),或者重新进行了赋值(在 operator=()里执行减一)。在以上两种情况中, ref_ptr< >都会通过调用 Referenced::unref()来执行减少引用计数值的操作。
因为添加的父节点grp已经是ref_ptr<>类型,所以goede没必要声明为osg::ref_ptr,将geode添加进grp父节点时,父节点(ref_ptr<>类型)会把子节点Geode的引用计数值置1。
注意:但是尽管没有意义,为了养成习惯,建议都使用ref_ptr< >,以保证 OSG 的内存管理工作正确
以下为正确的代码,该代码减小内存开辟动作,虽效率高一点但是建议还是用上面的代码,不要省ref_ptr< >,避免给自己挖坑。
下面代码会产生错误,编译时报析构函数为保护成员。
ref_ptr< >类型的变量只能够指向派生自Referenced 的对象,或者与Referenced类有相同接口的对象(若不满足,编译器会报错误)。
将派生自 Referenced 的对象赋予 ref_ptr< >变量,这一动作将自动调用
Referenced::ref()并使引用计数加一。
《OpenSceneGraph快速入门指导》
原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/95042433