
總結
前面我們基本上已經完成對ViewerBase::frame()函數的探究,只剩下renderingTraversals()渲染遍歷的探究,雖然就剩下了一個函數,但是這卻是最重要的,不可少的一個步驟。他主要是完成對場景的篩選和繪制工作,以及很多線程的調度和同步工作也是在這個函數中完成的。前面的幾天我們主要是講解了完成三個主要的遍歷函數,我們來總結一下。
advance(simulationTime);? // 記錄場景的幀數,幀速率信息
eventTraversal();???????? // 處理場景的交互事件及其回調
updateTraversal();??????? // 處理場景的更新回調,以及分頁數據的更新
所以我們總結上面的三個動作主要是,更新用戶數據, 負責場景對象的運動和管理等等;而這里并沒有涉及到有關場 景篩選或繪制的源代碼,而是著重于有關用戶更新(APP)操作的各類內容,而這些代碼中 也幾乎沒有涉及到線程與多核處理的內容(分頁數據庫的處理線程是個例外,它并非是與場 景渲染相關的內容)。那么今天我們主要是講解renderingTraversals()函數。
四種線程模式
因為這里我們會涉及到OSG 目前 提供的四種線程模型。所以我們先來簡單的介紹一下他們。OSG 的視景器包括四種線程模型,可以使用 setThreadingModel 進行設置,不同的線程 模型在仿真循環(huán)運行時將表現出不同的渲染效率和線程控制特性。通常而言,這四種線程的 特性如下:
SingleThreaded:單線程模型。OSG 不會創(chuàng)建任何新線程來完成場景的篩選和渲染,因 而也不會對渲染效率的提高有任何助益。它適合任何配置下使用。
CullDrawThreadPerContext:OSG?將為每一個圖形設備上下文(GraphicsContext)創(chuàng)建 一個圖形線程,以實現并行的渲染工作。如果有多個 CPU 的話,那么系統(tǒng)將嘗試把線程分 別放在不同的 CPU 上運行,不過每一幀結束前都會強制同步所有的線程。
DrawThreadPerContext:這一線程模型同樣會為每個 GraphicsContext 創(chuàng)建線程,并分配 到不同的 CPU 上。十分值得注意的是,這種模式會在當前幀的所有線程完成工作之前,開 始下一幀。
CullThreadPerCameraDrawThreadPerContext:這一線程模型將為每個 GraphicsContext 和每個攝像機創(chuàng)建線程,這種模式同樣不會等待前一次的渲染結束,而是返回仿真循環(huán)并再 次開始執(zhí)行 frame 函數。如果您使用四核甚至更高的系統(tǒng)配置,那么使用這一線程模型將 大限度地發(fā)揮多 CPU 的處理能力。
與 DrawThreadPerContext 和 CullThreadPerCameraDrawThreadPerContext 這兩種同樣可 以用于多 CPU 系統(tǒng),且相對更有效率的線程模型相比,CullDrawThreadPerContext 的應用范 圍比較有限;而 SingleThreaded 模式在單核以及配置較低的系統(tǒng)上運行穩(wěn)定。
今天只是對renderingTraversals(); // 場景的渲染遍歷工作,開一個小頭,因為它的內容比較的豐富,所以我需要一些時間梳理一下思路。