探索未知種族之osg類生物---起源

任何程序都是有生命的鹅髓,是生命就需要呼吸。例如普通的windows程序廓八,當運行完main()函數(shù)后奉芦,就需要進入消息循環(huán)赵抢,來監(jiān)聽用戶的各種操作,以便做出及時的回應声功。這樣的每次循環(huán)就像生命的每次呼吸烦却,來維持生命體征。

osg的程序不僅僅需要消息循環(huán)來監(jiān)聽用戶的鼠標先巴、鍵盤等操作其爵,同時也得具備了渲染循環(huán)。當然隨著我們的對osg的深入了解會發(fā)現(xiàn)伸蚯,osg的事件監(jiān)聽和渲染循環(huán)是串行的摩渺。但是當我們把osg與MFC(QT)等結合時,相應UI上的鼠標剂邮,鍵盤事件的同時也要兼顧可能發(fā)生在osg中的效果摇幻,所以一般的osg程序起碼需要兩個并行的線程(例如osg與qt結合使用,為了保持足夠靈敏的相應速度就需要把QTUI和osg渲染看成兩種生命挥萌,分為兩個線程)來維持它的正常運行绰姻。我們今天就是要解讀osg程序賴以生存的每次呼吸。

首先我們得找到osg是用什么呼吸的引瀑,就想地球上的一般生物都是用鼻子呼吸狂芋,我們又大概得知道鼻子長在生物的那個位置。這樣我們才可以開始我們的研究伤疙。當然我們肯定得有osg的源碼银酗,就像我們研究生物的呼吸先得有這種生物的身體。有了身體我們還得持續(xù)的觀察一個有生命的生物徒像,所以我們最先得到osg的可運行的程序就是example中的各種程序黍特。其中大部分的程序main()函數(shù)的最后部分都是調(diào)用一下viewer.run()。

所以我們可以有一個模糊的判斷這一類的通過調(diào)用viewer類的run函數(shù)的程序锯蛀,他的呼吸系統(tǒng)可能是通過run完成的灭衷。但是run()函數(shù)是一個單獨的一行,按說他執(zhí)行完畢以后程序就會結束了旁涤,所以我們有了新的判斷osg的每一幀的調(diào)用的入口是在run()函數(shù)中的翔曲。這是osg程序存在的一種形式(或者叫獨立運行模式)。Osg還有另一種存在形式劈愚,就是和各種UI混合使用瞳遍,例如qt與osg結合使用,MFC與osg結合使用等等菌羽。我們可以從examples/osgviewerQt 的例子掠械,可以根據(jù)上一個的思路,呼吸不是一次性的動作,是只要存活就會一直存在的猾蒂。所以從osgviewerQt.cpp中根據(jù)以前的經(jīng)驗定位到timer (計時器),他每次timeout觸發(fā)時調(diào)用的函數(shù)update()中一定包含了osg的每一幀的調(diào)用的入口均唉。

根據(jù)上面兩種osg的存活形式,可以進行進一步的確認肚菠,究竟哪里才是維持osg生命體征的位置舔箭。Viewer.run()函數(shù)(OSG Core/osgViewer/Viewer.cpp)最后會繼續(xù)調(diào)用ViewerBase::run()函數(shù)(OSG Core/osgViewer/ViewerBase.cpp),

//OSG Core/osgViewer/Viewer.cppintViewer::run(){if(!getCameraManipulator()&&getCamera()->getAllowEventFocus()){setCameraManipulator(newosgGA::TrackballManipulator());}setReleaseContextAtEndOfFrameHint(false);returnViewerBase::run();}

//OSG Core/osgViewer/ViewerBase.cppintViewerBase::run(){if(!isRealized()){realize();}constchar*run_frame_count_str=getenv("OSG_RUN_FRAME_COUNT");unsignedintrunTillFrameNumber=run_frame_count_str==0?osg::UNINITIALIZED_FRAME_NUMBER:atoi(run_frame_count_str);while(!done()&&(run_frame_count_str==0||getViewerFrameStamp()->getFrameNumber()<runTillFrameNumber)){doubleminFrameTime=_runMaxFrameRate>0.0?1.0/_runMaxFrameRate:0.0;osg::Timer_tstartFrameTick=osg::Timer::instance()->tick();if(_runFrameScheme==ON_DEMAND){if(checkNeedToDoFrame()){frame();}else{// we don't need to render a frame but we don't want to spin the run loop so make sure the minimum// loop time is 1/100th of second, if not otherwise set, so enabling the frame microSleep below to// avoid consume excessive CPU resources.if(minFrameTime==0.0)minFrameTime=0.01;}}else{frame();}// work out if we need to force a sleep to hold back the frame rateosg::Timer_tendFrameTick=osg::Timer::instance()->tick();doubleframeTime=osg::Timer::instance()->delta_s(startFrameTick,endFrameTick);if(frameTime<minFrameTime)OpenThreads::Thread::microSleep(static_cast(1000000.0*(minFrameTime-frameTime)));}return0;}

我們在ViewerBase::run()中繼續(xù)耐心的尋找就會發(fā)現(xiàn)有一個特殊的函數(shù)frame()蚊逢,為什么特殊呢层扶?因為frame的英文的意思就是’幀’,而我們學渲染都知道’幀’代表屏幕上一幅畫时捌,這和osg庫的本質就聯(lián)系在了一起怒医。Osg就是一個庫,一個在計算機屏幕上作畫的庫奢讨。所以ViewerBase::frame()就是我們要找的osg中會呼吸的地方。同樣我們在examples/osgviewerQt中也會發(fā)現(xiàn)焰薄,timer每到設定事件就會調(diào)用update()函數(shù)拿诸,而qt的update()函數(shù)在內(nèi)部就會調(diào)用paintEvent()函數(shù),我們在osgviewerQt.cpp的paintEvent()函數(shù)中也會發(fā)現(xiàn)osg::CompositeViewer的update函數(shù)塞茅,而osg::CompositeViewer繼承自ViewerBase亩码,所以最后也會定位到ViewerBase::frame()。這樣我們就可以確定osg這類生物的呼吸的入口是ViewerBase::frame()函數(shù)野瘦。終于我們打開了通往新世界的大門描沟,下一步就是經(jīng)歷輪回,看看osg這類生物是怎么生存的鞭光。

歡迎大家來我的新家看一看?3wwang個人博客-記錄走過的技術之路

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吏廉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子惰许,更是在濱河造成了極大的恐慌席覆,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汹买,死亡現(xiàn)場離奇詭異佩伤,居然都是意外死亡,警方通過查閱死者的電腦和手機晦毙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門遏乔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肃拜,“玉大人,你說我怎么就攤上這事±龋” “怎么了店归?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我邀层,道長,這世上最難降的妖魔是什么遂庄? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任寥院,我火速辦了婚禮,結果婚禮上涛目,老公的妹妹穿的比我還像新娘秸谢。我一直安慰自己,他們只是感情好霹肝,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布估蹄。 她就那樣靜靜地躺著,像睡著了一般沫换。 火紅的嫁衣襯著肌膚如雪臭蚁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天讯赏,我揣著相機與錄音垮兑,去河邊找鬼。 笑死漱挎,一個胖子當著我的面吹牛系枪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播磕谅,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼私爷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了膊夹?” 一聲冷哼從身側響起衬浑,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎割疾,沒想到半個月后嚎卫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡宏榕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年拓诸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片麻昼。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡奠支,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出抚芦,到底是詐尸還是另有隱情倍谜,我是刑警寧澤迈螟,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站尔崔,受9級特大地震影響答毫,放射性物質發(fā)生泄漏。R本人自食惡果不足惜季春,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一洗搂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧载弄,春花似錦耘拇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至逞刷,卻和暖如春嘉涌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背夸浅。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工洛心, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人题篷。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像厅目,于是被迫代替她去往敵國和親番枚。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容