osg学习(五)OSG_NOTIFY消息通知

本文介绍了osg程序的信息输出级别,包括osg::NOTICE等7个级别,以及如何设置输出信息的优先级,如通过环境变量OSG_NOTIFY_LEVEL或程序中的osg::setNotifyLevel()。osg的消息通知采用单实例模式,通过NotifyStream或NullStream处理,其中NotifyStream在遇到std::endl时会触发回调函数,可能将信息输出到文件或弹窗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、osg程序的信息输出分为7个级别,分别是

osg/Notify
enum NotifySeverity {
    ALWAYS=0,
    FATAL=1,
    WARN=2,
    NOTICE=3,
    INFO=4,
    DEBUG_INFO=5,
    DEBUG_FP=6
};

信息的严重性级别依次升高。osg支持设置输出信息的严重性阈值,不高于该阈值的信息会进行输出,默认的阈值是是osg::NOTICE。

二、优先级的设置有几种方式:

1、环境变量,OSG_NOTIFY_LEVEL或OSGNOTIFYLEVEL,

2、程序设置,osg::setNotifyLevel()

三、信息输出的使用:

OSG_INFO << "\tAttrib \"" << name << "\""
                         << " loc=" << loc
                         << " size=" << size
                         << std::endl;

其中OSG_INFO是这样定义的:

osg/Notify
#define OSG_NOTIFY(level) if (osg::isNotifyEnabled(level)) osg::notify(level)
#define OSG_ALWAYS OSG_NOTIFY(osg::ALWAYS)
#define OSG_FATAL OSG_NOTIFY(osg::FATAL)
#define OSG_WARN OSG_NOTIFY(osg::WARN)
#define OSG_NOTICE 
<think>好的,用户之前问了关于C++ vector容器的初始化,现在又转向了OpenSceneGraph中的osg::ref_ptr<osg::Group>的使用方式。我需要先确认用户的需求是什么。可能他们在使用OSG进行3D开发,遇到了智能指针管理的问题,或者想了解如何正确使用Group节点。 首先,osg::ref_ptr是OSG中的智能指针,用于自动管理对象的引用计数,防止内存泄漏。而osg::Group是一个重要的容器节点,可以包含多个子节点。用户可能需要了解如何创建、管理这些节点,以及如何正确使用智能指针来维护它们的生命周期。 接下来,我需要回顾OSG中的基础概念。OSG使用引用计数机制,每个继承自osg::Referenced的类都可以被osg::ref_ptr管理。osg::Group作为常见的节点类型,用于组织场景图,添加或移除子节点。用户可能想知道如何初始化、赋值、传递这个智能指针,以及在使用过程中需要注意的事项,比如循环引用的问题。 用户之前的问题是关于初始化的,所以他们可能对osg::ref_ptr的初始化方式特别感兴趣。需要分步骤说明,包括创建、赋值、作为函数参数、返回、以及添加到场景图中的方法。同时,应该提到内存管理的注意事项,比如避免直接new而不使用ref_ptr,或者循环引用导致的内存泄漏。 还需要考虑用户可能的错误用法,比如错误地将裸指针赋值给ref_ptr,或者在不需要时手动释放内存。此外,可能需要强调OSG的场景图结构和智能指针如何协同工作,确保节点正确被引用和释放。 最后,总结使用时需要遵循的最佳实践,比如始终使用ref_ptr包裹OSG对象,正确添加子节点,避免循环引用,使用有效的调试方法等。这样用户能有一个清晰的指南来正确使用osg::ref_ptr<osg::Group>,提升代码的健壮性和效率。</think>以下是对`osg::ref_ptr<osg::Group>`使用方式的详细说明,涵盖其核心机制、典型用法及注意事项: --- ### 1. **基本概念** - **`osg::ref_ptr`**:OpenSceneGraph(OSG)中的智能指针模板类,基于引用计数自动管理对象生命周期。 - **`osg::Group`**:OSG场景图中的容器节点,可包含多个子节点(如`Geode`或其他`Group`),用于组织场景层级。 --- ### 2. **核心规则** - **引用计数**:所有继承自`osg::Referenced`的类(如`osg::Group`)均可由`osg::ref_ptr`管理。 - **自动释放**:当引用计数归零时,对象自动销毁,无需手动`delete`。 - **禁止栈对象**:OSG节点必须通过`new`创建并由`osg::ref_ptr`管理。 --- ### 3. **典型使用方式** #### (1) **创建与初始化** ```cpp // 直接构造并赋值 osg::ref_ptr<osg::Group> root = new osg::Group; // 分步创建 osg::Group* rawGroup = new osg::Group; osg::ref_ptr<osg::Group> groupPtr(rawGroup); // 引用计数+1 ``` #### (2) **添加子节点** ```cpp osg::ref_ptr<osg::Geode> geode = new osg::Geode; root->addChild(geode); // geode的引用计数+1 ``` #### (3) **传递与赋值** ```cpp // 传递智能指针(安全) void processGroup(osg::ref_ptr<osg::Group> group) { group->setName("Processed"); } processGroup(root); // 引用计数临时+1,函数返回后恢复 // 赋值操作 osg::ref_ptr<osg::Group> anotherGroup = root; // 引用计数+1 ``` #### (4) **作为函数返回值** ```cpp osg::ref_ptr<osg::Group> createScene() { osg::ref_ptr<osg::Group> scene = new osg::Group; // ... 构建场景 return scene; // 引用计数正确转移 } ``` --- ### 4. **内存管理注意事项** #### (1) **禁止混用裸指针** ```cpp // 错误示例:裸指针可能提前释放! osg::Group* unsafeGroup = new osg::Group; root->addChild(unsafeGroup); // 必须用ref_ptr包裹 // 正确做法 osg::ref_ptr<osg::Group> safeGroup = new osg::Group; root->addChild(safeGroup); ``` #### (2) **避免循环引用** ```cpp osg::ref_ptr<osg::Group> groupA = new osg::Group; osg::ref_ptr<osg::Group> groupB = new osg::Group; groupA->addChild(groupB); // groupB引用计数+1 groupB->addChild(groupA); // 循环引用!引用计数无法归零 // 解决方案:手动解除循环或使用弱指针(osg::observer_ptr) ``` #### (3) **与STL容器结合** ```cpp std::vector<osg::ref_ptr<osg::Group>> groupList; groupList.push_back(new osg::Group); // 安全存储 ``` --- ### 5. **调试技巧** - **查看引用计数**: ```cpp std::cout << "Reference count: " << root->referenceCount() << std::endl; ``` - **OSG内存检测工具**:通过`OSG_NOTIFY_LEVEL=INFO`环境变量输出内存操作日志。 --- ### 6. **典型应用场景** ```cpp // 构建场景图 osg::ref_ptr<osg::Group> buildScene() { osg::ref_ptr<osg::Group> root = new osg::Group; osg::ref_ptr<osg::Geode> geode = createGeometry(); root->addChild(geode); // 添加几何体 root->addChild(createLights()); // 添加光源节点 return root; } // 主函数中安全使用 int main() { osg::ref_ptr<osg::Group> scene = buildScene(); osgViewer::Viewer viewer; viewer.setSceneData(scene); // 设置场景根节点 return viewer.run(); } ``` --- ### 总结表格 | 操作 | 代码示例 | 说明 | |----------------------|---------------------------------------------|--------------------------------| | 创建对象 | `osg::ref_ptr<osg::Group> root = new osg::Group;` | 必须通过`new`分配 | | 添加子节点 | `root->addChild(childNode);` | 自动管理子节点引用 | | 函数参数传递 | `void func(osg::ref_ptr<osg::Group> group)` | 安全传递所有权 | | 检测引用计数 | `group->referenceCount()` | 调试内存管理问题 | 遵循这些规则可有效避免内存泄漏和野指针问题,是OSG开发的核心实践之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值