【OSG】osgearthviewer读取earth文件,代码解析(earth文件读取的一帧)

本文详细解析了使用osgEarthViewer加载Earth文件的过程,重点介绍了osgDB加载机制及地球文件的具体读取步骤。

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

转载:[原][osgearth]osgearthviewer读取earth文件,代码解析(earth文件读取的一帧)

跑osgearthviewer程序

使用一个earth文件做参数传入

跟进代码。

首先osgearthviewer程序加载earth的方式分为两种:

 

1.根据earth文件(load方式)

2.使用SDK加载(create方式)

 

我们使用earth文件是load方式,直接看load函数,定位到这个位置

    // load an earth file, and support all or our example command-line options
    // and earth file <external> tags    
    osg::Node* node = MapNodeHelper().load(arguments, &viewer);

上面的函数是用来加载earth文件的,仔细看一下这个函数

发现这个函数是通过osgDB的加载机制来实现earth文件的加载。

 

下面我们先要搞清楚的是osgDB的加载机制

 

这是osgDB读取的调用顺序

回到,我们自己的程序,我将代码调试过程截图:

 

 

这里有不少默认的属性,而我们是定位到自定义的部分:(下图)

因为,我只用了一个传入参数,所以,这个循环只执行一次,就是调用了一次readRefNodeFile文件

 

这个函数好像是管理缓存什么的,我们在函数里定位到这里:(下图)

 

这个read才是开始真正解析数据了。

复制代码

  1 ReaderWriter::ReadResult Registry::read(const ReadFunctor& readFunctor)
  2 {
        
       ......关于osga和zip文件的
 52     // first attempt to load the file from existing ReaderWriter's第一次尝试从现有ReaderWriter的加载文件
 53     AvailableReaderWriterIterator itr(_rwList, _pluginMutex);
 54     for(;itr.valid();++itr)
 55     {
 56         ReaderWriter::ReadResult rr = readFunctor.doRead(*itr);
 57         if (readFunctor.isValid(rr)) 
 58             return rr;
 59         else results.push_back(rr);
 60     }
 61 
 62     // check loaded archives.检查加载的档案
 63     AvailableArchiveIterator aaitr(_archiveCache, _archiveCacheMutex);
 64     for(;aaitr.valid();++aaitr)
 65     {
 66         ReaderWriter::ReadResult rr = readFunctor.doRead(*aaitr);
 67         if (readFunctor.isValid(rr)) 
 68             return rr;
 69         else
 70         {
 71             // don't pass on FILE_NOT_FOUND results as we don't want to prevent non archive plugins that haven't been
 72             // loaded yet from getting a chance to test for the presence of the file.
 73             if (rr.status()!=ReaderWriter::ReadResult::FILE_NOT_FOUND) results.push_back(rr);
 74         }
 75     }
 76 
 77     // now look for a plug-in to load the file.现在寻找一个插件加载文件!!!
 78     std::string libraryName = createLibraryNameForFile(readFunctor._filename);
 79     if (loadLibrary(libraryName)!=NOT_LOADED)
 80     {
 81         for(;itr.valid();++itr)
 82         {
 83             ReaderWriter::ReadResult rr = readFunctor.doRead(*itr);
 84             if (readFunctor.isValid(rr)) 
 85                 return rr;
 86             else results.push_back(rr);
 87         }
 88     }
 89 
 90     //If the filename contains a server address and wasn't loaded by any of the plugins, try to find a plugin which supports the server
 91     //protocol and supports wildcards. If not successfully use curl as a last fallback
 92     if (containsServerAddress(readFunctor._filename))
 93     {
 94         ReaderWriter* rw = getReaderWriterForProtocolAndExtension(
 95             osgDB::getServerProtocol(readFunctor._filename),
 96             osgDB::getFileExtension(readFunctor._filename)
 97         );
 98 
 99         if (rw)
100         {
101             return readFunctor.doRead(*rw);
102         }
103         else
104         {
105             return  ReaderWriter::ReadResult("Warning: Could not find the .curl plugin to read from server.");
106         }
107     }
108 
109     if (results.empty())
110     {
111         return ReaderWriter::ReadResult("Warning: Could not find plugin to read objects from file \""+readFunctor._filename+"\".");
112     }
113 
114     // sort the results so the most relevant (i.e. ERROR_IN_READING_FILE is more relevant than FILE_NOT_FOUND) results get placed at the end of the results list.
115     std::sort(results.begin(), results.end());
116     ReaderWriter::ReadResult result = results.back();
117 
118     if (result.message().empty())
119     {
120         switch(result.status())
121         {
122             case(ReaderWriter::ReadResult::FILE_NOT_HANDLED): result.message() = "Warning: reading \""+readFunctor._filename+"\" not supported."; break;
123             case(ReaderWriter::ReadResult::FILE_NOT_FOUND): result.message() = "Warning: could not find file \""+readFunctor._filename+"\"."; break;
124             case(ReaderWriter::ReadResult::ERROR_IN_READING_FILE): result.message() = "Warning: Error in reading to \""+readFunctor._filename+"\"."; break;
125             default: break;
126         }
127     }
128 
129     return result;
130 }

复制代码

 在第一次进入次函数时

它在78行  获取了插件叫osgDB_earth.dll(osgdb_earthd.dll)

它在第83行 开始加载插件调用了doRead函数

而doRead函数就是利用osgDB的机制调用,第三方插件osgDB_Earth中的读取方式:

正式开始读取本地earth文件(为什么是本地,因为读取服务器上的似乎有另外一套处理方案)振奋人心!

readstring直接调用doRead(URI.cpp)

 但是,doRead当函数调用到加载URIReadCallback的时候,给我带来不少麻烦

这里使用的类是osgearth的Registry构造,让我一度和osgDB的Registry搞混。

调试了好久,而且由于里面加载了一个osgText::readFontFile("arial.ttf");

所以导致之前的readImplementation又被调用了一遍,非常打调试的连续性······MBD

继续在ReaderWriterOsgEarth的readNode函数中往下

一番磨难,似乎看到了胜利的曙光,进入到readNode函数中:

看到了序列化,关于序列化,我有另外一个博客,可以看下

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值