我們今天進(jìn)入上一節(jié)的遺留問(wèn)題Renderer::draw()的探究。

1、從_drawQueue中取出其中一個(gè)sceneView對(duì)象。SceneView是對(duì)scene和view類的封裝,通過(guò)他可以方便的訪問(wèn)到scene或者view中的成員,以及最主要的作用是封裝了更新,挑選,和繪制遍歷,但是并不啟用DatabasePager。
2、sceneView->collateReferencesToDependentCameras();得到所有的sceneView依賴的相機(jī)的引用,因?yàn)槲覀冋谶\(yùn)行與主線程并行的繪制線程,所以取消引用的camera有可能還在被此渲染線程使用,所以為了防止這種情況,我們將引用所有這些Camera并且一旦我們清除了這些引用那么就完成了整個(gè)渲染調(diào)度。
3、_compileOnNextDraw,它代表接下來(lái)的渲染是否已經(jīng)進(jìn)行編譯,如果為true,則進(jìn)入Renderer::compile()函數(shù),首先把compileOnNextDraw設(shè)置為false,然后我們從sceneView中得到scene的根節(jié)點(diǎn)sceneView->getSceneData(),遍歷所有的場(chǎng)景中的節(jié)點(diǎn),把GLObjects的節(jié)點(diǎn)的狀態(tài)保存到狀態(tài)樹(shù)中。
4、執(zhí)行 Renderer::initialize,初始化 Renderer 繪制所需的基本變量。
5、下一步的工作是執(zhí)行 SceneView::getDynamicObjectCount 函數(shù)判斷場(chǎng)景視圖中動(dòng)態(tài)對(duì)象(設(shè)置為 DYNAMIC)的個(gè)數(shù),并執(zhí)行其回調(diào)類(此回調(diào)類派生自線程阻塞器 BlockCount,此處為 State::getDynamicObjectRenderingCompletedCallback,這個(gè)類的作用就是阻塞線程的執(zhí)行,并且可以設(shè)置一個(gè)阻塞計(jì)數(shù)值。計(jì)數(shù)的作用是:每當(dāng)阻塞器對(duì)象的 completed()函數(shù)被執(zhí)行一次,計(jì)數(shù)器就減一,直至減到零就釋放被阻塞的線程)的 completed 函數(shù)。在這里completed函數(shù)的主要作用是為了在多線程工作時(shí)保證動(dòng)態(tài)(DYNAMIC)對(duì)象的更改不會(huì)影響到渲染管線而實(shí)現(xiàn)的:正如 OSG 基礎(chǔ)教程中所強(qiáng)調(diào)的那樣,只有設(shè)置為 setDataVariance(DYNAMIC)的對(duì)象才可以在仿真循環(huán)中被隨時(shí)更改。
6、執(zhí)行 OpenGLQuerySupport::checkQuery 函數(shù),判斷是否可以使用 OpenGL 查詢對(duì)象(query objects)。
7、執(zhí)行 OpenGLQuerySupport::beginQuery 函數(shù),創(chuàng)建或者獲取一個(gè)查詢對(duì)象,其工作主要是獲取并統(tǒng)計(jì) GPU 計(jì)算的時(shí)間
8、執(zhí)行 SceneView::draw 函數(shù),果然,場(chǎng)景的繪制工作最后也是在 SceneView 函數(shù)中完成的!雖然osg在osg::Util::SceneView的頭文件中指出,這個(gè)sceneView類已經(jīng)被廢除了,存在的意義就是為了向前兼容。但是經(jīng)過(guò)我們的探究發(fā)現(xiàn),sceneView才是進(jìn)行場(chǎng)景的篩選以及繪制工作的主要類,而渲染器類 Renderer 只是一個(gè)更為方便和直觀的公用接口而已。SceneView::draw 函數(shù)就是用來(lái)繪制經(jīng)過(guò)cull裁剪以后得到的”可繪制盒”內(nèi)的所有物體。而我們還沒(méi)有進(jìn)行cull函數(shù)的介紹,所以這個(gè)draw函數(shù)我們也得暫放一段時(shí)間。
9、將已經(jīng)結(jié)束繪制的場(chǎng)景視圖對(duì)象再次追加到_availableQueue 隊(duì)列中,這樣可以保證該隊(duì)列始終保存有兩個(gè) SceneView 對(duì)象,以正確實(shí)現(xiàn)場(chǎng)景的篩選和渲染工作
10、_querySupport->endQuery(state);得到GPU 計(jì)算的時(shí)間,并記錄Draw traversal統(tǒng)計(jì)的所有時(shí)間
11、最后要取消所有的camera的引用。