[原][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函數中:

看到了序列化,關於序列化,我有另外一個博客,可以看下

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM