探索未知种族之osg类生物---器官初始化四
上一節(jié)我們對完成了對osg生物內(nèi)部非常重要器官graphicsContext的初始化工作。這樣就可保證我們場景中至少有一個graphicContext存在,不至于剛出生就面臨夭折。我們根據(jù)上一節(jié)中osg代碼的研究也就知道了,在我們正常使用osg時,是怎么完成對camera以及graphicContext的創(chuàng)建的了。
回到Viewer::realize()中我們繼續(xù)向下看,現(xiàn)在我們對osg::DisplaySettings以及osg::GraphicsContext::WindowingSystemInterface,有了新的認(rèn)識,我在這里再補充一張camera,graphicContext以及windowingSystemInterface的關(guān)系圖有利于大家進(jìn)一步了解osg的內(nèi)部組成。
回到Viewer::realize()中我們繼續(xù)向下看,得到所有的GraphicsContext,遍歷所有的GraphicsContext,然后判斷是否設(shè)置了同步交換緩沖區(qū)(這一般是渲染的最后一步),這是osg提供的多機同步swapbuffer機制,他會默認(rèn)調(diào)用內(nèi)置的swapbuffer的回調(diào)函數(shù)(osg::SyncSwapBuffersCallback中,作用主要是等待client端的同步鎖,實現(xiàn)多機同步執(zhí)行swapbuffer)。如果developer想干預(yù)的話 可以調(diào)用 osg::GraphicsContext::setSwapCallback(SwapCallback* rc)來設(shè)置自定義的緩存交換回調(diào)。自定義的回調(diào)必須調(diào)用GraphicsContext::swapBuffersImplementation()函數(shù).
再根據(jù)所依據(jù)的平臺(windows,linux,mac等)默認(rèn)制定的,或者用戶后期修改的最大紋理池和最大對象緩沖池的大小,進(jìn)一步對各個graphicsContext的相應(yīng)屬性值進(jìn)行設(shè)置。然后正式完成對graphicsContext的初始化定義,下一步就是通過調(diào)用gc.realize()來使graphicsContext處于可用的狀態(tài)。Osg::GraphicsContext::realize()函數(shù)的實現(xiàn)都是在它的繼承類中通過realizeImplementation()函數(shù)完成的。
特別是windows平臺的實現(xiàn),使用windows+opengl的同學(xué)對這一段GraphicsWindowWin32::realizeImplementation()函數(shù)肯定非常了解,因為這里會涉及到很多windows平臺特有的一些屬性,就不做過多的介紹了,以后有機會我會再寫一份opengl的入門教程,其中肯定會提到函數(shù)中涉及的東西。敬請期待。
當(dāng)GraphicsContext可用了,就需要更新上下文gc->makeCurrent()。那我們就看看GraphicsContext::makeCurrent()完成了什么工作。
gc->makeCurrent()
GraphicsContext::makeCurrent()首先判斷opengl與osg是否是同一個線程,(使用qt5+osg3.x的同學(xué)一定遇到過osg的threadmode只能設(shè)置singlethread。其他三種threadmode都會報一個同樣的錯誤,錯誤的原因就是這里。至于怎么完美的結(jié)合qt5與osg3,請移步到我的github下?https://github.com/JimmieKJ/osgQTWidget?有具體的實現(xiàn)細(xì)節(jié))。其實GraphicsContext::makeCurrent()的根本是通過調(diào)用子類的makeCurrentImplementation()實現(xiàn)。
??
當(dāng)我們移步到bool GraphicsWindowWin32::makeCurrentImplementation()同樣會發(fā)現(xiàn),這里和使用opengl的程序有很大的相同之處,其實就是把dc和rc進(jìn)行綁定。當(dāng)makeCurrentImplementation返回true的時候,就代表graphicsContext更新成功。然后就是opengl的思路,需要解綁hc和rc防止資源浪費,這就需要調(diào)用gc->releaseContext(),其實就是調(diào)用子類的releaseContextImplementation()函數(shù)。
再次聚焦到realize函數(shù)上(/src/osgViewer/Viewer.cpp::realize()函數(shù)),_incrementalCompileOperation,用于預(yù)編譯GraphicContext,主要作用是,想在程序運行開始時就加在一個資源文件但是又不想或者沒有到顯示到界面的時機,則會用到這個預(yù)加載操作。具體的用法如下:
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | //從Viewer獲取 osgUtil::IncrementalCompileOperation的指針: osgUtil::IncrementalCompileOperation* pIcompOperation = viewer.getIncrementalCompileOperation();//從Viewer獲取 osgUtil::IncrementalCompileOperation的指針: // 創(chuàng)建compileSet: osg::ref_ptr compileSet = osgUtil::IncrementalCompileOperation::CompileSet(NODE,true); //從CompileCompletedCallback派生新類,然后重寫Completed函數(shù),在內(nèi)部隱藏節(jié)點: ?? //將 派生類 綁定到 compileSet。 compileSet->compileSet->_compileCompletedCallback =? newCompileCompletedCallback; //設(shè)置 IncrementalCompileOperation 過期策略 pIcompOperation->setCompileAllTillFrameNumber(50); 再往下就是使鼠標(biāo)聚焦到osg的繪制窗口上這個一個功能。 // initialize the global timer to be relative to the current time. osg::Timer::instance()->setStartTick(); // pass on the start tick to all the associated event queues setStartTick(osg::Timer::instance()->getStartTick()); // configure threading. setUpThreading(); |
首先調(diào)用 osg::Timer::setStartTick 函數(shù),啟動 OSG 內(nèi)部定時器并開始計時。
隨后,?Viewer::setStartTick 函數(shù)的工作是找到當(dāng)前視景器和所有 GraphicsContext 設(shè)備的事件隊列_eventQueue,并設(shè)定它們的啟動時刻為當(dāng)前時間。下一行是調(diào)用 ViewerBase::setUpThreading 函數(shù)(這個多線程問題我們以后再深入討論)
請回到 realize 函數(shù),現(xiàn)在這個函數(shù)的執(zhí)行已經(jīng)接近了尾聲,不過我們又遇到了一個問題:編譯上下文(也就是 Compile Contexts,)如果要啟用它的話并不困難,只需要在調(diào)用 realize 之前執(zhí)行:osg::DisplaySettings::instance()->setCompileContextsHint(true);隨后,正如您在 realize 函數(shù)的 最后一個for循環(huán)看到的,系統(tǒng)將設(shè)法遍歷所有可能的GraphicsContext 設(shè)備,針對它們分別再各自添加一個新的 GraphicsContext 設(shè)備(也就是說如果系統(tǒng)中已經(jīng)有了數(shù)個圖形上下文,那么現(xiàn)在又將新增同樣數(shù)量的圖形上下文與之對應(yīng)),所用的函數(shù)為?GraphicsContext::getOrCreateCompileContext。
這之后,分別執(zhí)行了創(chuàng)建圖形線程,設(shè)置 CPU 依賴性,以及啟動圖形線程的工作,具體的實現(xiàn)內(nèi)容可以暫時忽略。觀察 getOrCreateCompileContext 函數(shù)的內(nèi)容,很快我們就可以發(fā)現(xiàn)其中的重點:這些新增的 GraphicsContext 對象使用了 pBuffer 的特性,并與對應(yīng)的已有對象共享同一個圖形上下文(Traits::sharedContext 特性)。事實上,這是 OSG 利用 OpenGL 的像素緩存(Pixel Buffer)技術(shù),為圖形上下文的后臺編譯提供的一種新的解決方案。這樣不僅可以提高圖形刷新的速度,還可以方便用戶為某一特定的 GraphicsContext 設(shè)備添加特殊的處理動作,方法是使用osg::GraphicsContext::getCompileContext 獲取后臺圖形上下文,再使用 GraphicsContext::add函數(shù)向其中追加 osg::Operation 對象,類似的例子可以參看 osgterrain。
歡迎大家來我的新家看一看?3wwang個人博客-記錄走過的技術(shù)之路
轉(zhuǎn)載于:https://www.cnblogs.com/wang985850293/p/10436510.html
總結(jié)
以上是生活随笔為你收集整理的探索未知种族之osg类生物---器官初始化四的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安装天然气需要哪些费用?
- 下一篇: 没有基础,想学肚皮舞,费用贵吗?