OpenSceneGraph | OSG如何存储带纹理osgb格式可以节省空间

解决OSG存储带纹理osgb格式数据量大的问题,通过设置WriteImageHint为IncludeFile实现压缩存储,有效节省空间。

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

  在使用OSG(OpenSceneGraph)存储带纹理osgb格式的过程中,大家会遇到这样一种情况:存储后的osgb文件所占用的大小远大于原始文件的大小,几倍至几十倍。这是为何呢?原因是OSG默认的存储格式是不压缩存储,所以解决方案就是设置参数将存储格式改为压缩存储。方法如下:

osg::ref_ptr<osgDB::ReaderWriter::Options> options = new osgDB::ReaderWriter::Options;
options->setOptionString("WriteImageHint=IncludeFile");			// 设置压缩
osgDB::writeNodeFile(*(node.get()), osgb_path, options);

  如下文档可以找到解决方法的来源:

$ osgconv --format osgb 
Plugin osgPlugins-3.3.9/osgdb_osg.so 
{ 
   ReaderWriter : OSG Reader/Writer 
   { 
       features   : readObject readNode writeObject writeNode   
       extensions : .osg                           OpenSceneGraph Ascii file format 
       extensions : .osgs                          Pseudo OpenSceneGraph file loaded, with file encoded in filename string 
       options    : OutputTextureFiles             Write out the texture images to file 
       options    : includeExternalReferences      Export option 
       options    : precision                      Set the floating point precision when writing out files 
       options    : writeExternalReferenceFiles    Export option 
   } 
   ReaderWriter : OpenSceneGraph Native Format Reader/Writer 
   { 
       features   : readObject readImage readNode writeObject writeImage writeNode   
       extensions : .osg2                    OpenSceneGraph extendable format 
       extensions : .osgb                    OpenSceneGraph extendable binary format 
       extensions : .osgt                    OpenSceneGraph extendable ascii format 
       extensions : .osgx                    OpenSceneGraph extendable XML format 
       options    : Ascii                    Import/Export option: Force reading/writing ascii file 
       options    : Compressor=<name>        Export option: Use an inbuilt or user-defined compressor 
       options    : ForceReadingImage        Import option: Load an empty image instead if required file missed 
       options    : SchemaData               Export option: Record inbuilt schema data into a binary file 
       options    : SchemaFile=<file>        Import/Export option: Use/Record an ascii schema file 
       options    : WriteImageHint=<hint>    Export option: Hint of writing image to stream: <IncludeData> writes Image::data() directly; <IncludeFile> writes the image file itself to stream; <UseExternal> writes only the fi 
lename; <WriteOut> writes Image::data() to disk as external file. 
       options    : XML                      Import/Export option: Force reading/writing XML file 
   } 
} 

  上面文档中,有关WriteImageHint的项的描述(第26行):选择IncludeData是直接写入数据,无压缩,是默认选项。而includeFile则是写入流,按我的理解,就是将原始的影像数据流原原本本的写入osgb,原始的影像是压缩过的,比如jpg格式,那保存出来的osgb就是压缩过的。因此,将WriteImageHint设置为IncludeFile可以解决OSG存储带纹理osgb格式数据量大的问题,节省空间。

03-20
### OpenSceneGraphosgDB 的功能介绍 #### 一、osgDB 模块概述 `osgDB` 是 OpenSceneGraph (OSG) 提供的一个核心模块,主要用于文件读写操作以及场景图数据的序列化和反序列化。它支持多种三维模型格式的加载与保存,同时也提供了灵活的选项配置机制来满足不同的需求[^1]。 该模块的核心功能可以分为以下几个方面: - **文件读取**: `osgDB::readNodeFile()` 和其他类似的函数用于从磁盘或其他输入流中加载几何节点或整个场景图。 - **文件写入**: 如 `osgDB::writeNodeFile()` 函数允许将场景图中的对象保存到指定路径下的文件中。 - **插件扩展**: 支持通过动态链接库的形式增加新的文件格式解析器,从而增强其兼容性和灵活性。 #### 二、具体 API 解析 以下是几个常用的 `osgDB` 接口及其作用: ##### 1. 文件读取接口 ```cpp osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile("path/to/model.osg"); if (!loadedModel) { std::cerr << "Failed to load model." << std::endl; } ``` 上述代码片段展示了如何利用 `osgDB::readNodeFile()` 加载一个 `.osg` 格式的三维模型文件。如果返回值为空,则表示加载失败[^4]。 需要注意的是,在实际应用过程中可能会因为缺少必要的依赖项或者不匹配的编译设置而导致错误发生。因此建议开发者仔细检查 CMake 配置阶段是否正确启用了所需的功能组件。 ##### 2. 文件写入接口 对于需要导出处理后的场景结构至外部存储介质的情况,可以采用如下方式调用 `osgDB::writeNodeFile()` 方法完成任务: ```cpp bool success = osgDB::writeNodeFile(*rootNode, outputPath); if (!success) { std::cerr << "Export failed!" << std::endl; } else { std::cout << "Successfully exported scene graph." << std::endl; } ``` 这里额外指定了一个自定义参数 `"WriteImageHint=IncludeFile"` 来控制图像资源嵌套行为[^3]。此特性特别适用于希望保持原始纹理映射关系而不丢失任何细节的应用场合。 ##### 3. 单例模式初始化宏解释 关于提到的单例设计模式实现部分——即 `OSG_INIT_SINGLETON_PROXY` 宏展开后的作用原理分析如下所示: ```cpp #define OSG_INIT_SINGLETON_PROXY(ClassType, InstanceFunctionCall)\ ClassType* ClassType::_instancePtr = nullptr;\ std::mutex ClassType::_singletonMutex;\ ClassType* ClassType::getInstance()\ {\ if (!_instancePtr){\ std::lock_guard<std::mutex> lock(_singletonMutex);\ if(!_instancePtr){\ _instancePtr = InstanceFunctionCall;\ }\ }\ return _instancePtr;\ } ``` 这段模板化的代码片段实现了线程安全条件下的懒惰实例创建逻辑[^2]。每当程序首次请求访问某个特定类型的全局唯一实体时,都会触发内部构造过程;而后续再次获取同一类别的句柄则无需重复执行耗时的操作。 #### 三、注意事项与其他技巧提示 当尝试解决某些复杂问题比如无法正常渲染视窗(`osgViewer`)或是频繁崩溃现象时,除了验证基础环境搭建无误之外还需要关注以下几点事项: - 确认目标平台架构(x86 vs x64),并相应调整项目属性设定; - 明确所使用的第三方库版本号之间是否存在冲突风险; - 考虑启用调试断点逐步排查潜在隐患所在位置。 另外值得注意的一点是,尽管 `osgUtil::DelaunayTriangulator` 工具能够有效简化多边形网格拓扑结构转换流程,但它有可能移除一些边界上的孤立点位信息,所以在特殊应用场景下务必谨慎评估最终效果影响程度[^5]。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值