osg之osgDB读取文件详解

osg、osgEarth所有文件都是通过osgDB库来读取,通过Registry来查找文件拓展名对应的osg库(Registry是一个单例类,这个类特别重要,建议通读代码加深对此的理解),根据一定规则拼接成完成的osg库名并加载,通过ReaderWriter对象来完成节点的读取(ReaderWriter是读写节点的基类,可通过派生此类重写读写方法实现自己的读写格式)。

一、osg读取一个节点的方法

osg::ref_ptr<osg::Node> pNode = osgDB::readNodeFile("cow.osgt");

二、ReadFile这个文件是osgDB读取所有文件类型的接口封装,但是最终的读取都是由注册到Registry的代理来完成。
readNodeFile这个方法有两个参数一个是filename,一个是options。Options是一个对读取节点进行出来的对象,可对节点的三角面片进行进行优化,这个比较复杂,后面作为重点详细介绍,再次一笔带过。

/** Read an osg::Node from file. 
 1. Return valid osg::Node on success,
 2. return NULL on failure.
 3. The osgDB::Registry is used to load the appropriate ReaderWriter plugin
 4. for the filename extension, and this plugin then handles the request
 5. to read the specified file.*/
inline osg::Node* readNodeFile(const std::string& filename)
{
   
    return readNodeFile(filename,Registry::instance()->getOptions());
}
Node* osgDB::readNodeFile(const std::string& filename,const Options* options)
{
   
    ReaderWriter::ReadResult rr = Registry::instance()->readNode(filename,options);
    if (rr.validNode()) return rr.takeNode();
    if (rr.error()) OSG_WARN << rr.message() << std::endl;
    if (rr.notEnoughMemory()) OSG_INFO << "Not enought memory to load file "<<filename << std::endl;
    return NULL;
}

三、Registry这个类通过RegisterReaderWriterProxy类完成文件的读取,具体如下:
1、如果使用缓冲,我们会优先从缓冲文件读取节点
2、通过文件拓展名查找对应的模块名(例如:osgDB),根据规则拼接成完整的库名(osgdb_osg.dll),同时加载该库文件。
3、ReadFunctor对象的创建,以及通过doRead方法完成节点的读取,此方法有一个ReaderWriter对象参数,通过此对象的readNode方法完成最终的节点读取。我们也可以派生ReadWriter类重写其中的方法来完成自定义格式的文件读取。核心代码如下:

//1.通过读文件回调完成节点读取
//2.通过readNodeImplementation方法读取节点,最常用的方法
ReaderWriter::ReadResult readNode(const std::string& fileName, const Options* options, bool buildKdTreeIfRequired = true)
{
   
    ReaderWriter::ReadResult result;
    if (options && options->getReadFileCallback()) result = options->getReadFileCallback()->readNode(fileName, options);
    else if (_readFileCallback.valid()) result = _readFileCallback->readNode(fileName, options);
    else result = readNodeImplementation(fileName, options);

    if (buildKdTreeIfRequired) _buildKdTreeIfRequired(result, options);

    return result;
}
//ReadNodeFunctor对象至关重要,通过调用此对象的doRead方法完成读节点读取
ReaderWriter::ReadResult Registry::readNodeImplementation(const std::string& fileName,const Options* options)
{
   
#if 0

    osg::Timer_t startTick = osg::Timer::instance()->tick();
    ReaderWriter::ReadResult result = readImplementation(ReadNodeFunctor(fileName, options),Options::CACHE_NODES);
    osg::Timer_t endTick 
  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值