[OSG]OpenSceneGraph FAQ 以及OSG資源


1、地球背面的一個點,計算它在屏幕上的坐標,能得到嗎? 不是被擋住了嗎?

答:計算一個空間點的屏幕坐標,使用osgAPEx::GetScreenPosition函數。當空間點處於相機視空間內(不管它是否被別的物體遮擋)時,都是可以得到它對應的屏幕坐標的。

如何判斷一個點是否在地球背面?可以通過計算該點處垂直地面的方向UP,與相機方向的夾角,如果夾角為銳角,則可認為該點在地球背面。計算地球上任意點的UP方向使用osgAPEx::ComputeLocalUpVector。

2、OSG中可以播放視頻嗎?

答:可以使用quicktime插件或ffmpeg插件在OSG中播放視頻,quicktime插件的編譯需要QuickTimeSDK,ffmpeg插件的編譯需要ffmpeg庫(www.ffmpeg.org www.ffmpeg.com.cn  http://ffmpeg.arrozcru.org/builds/)。OSG的quicktime插件已經停止更新了,現在力推ffmpeg。

ffmpeg插件好像是從2.9版開始提供的。

利用視頻播放插件可以讀入avi等視頻文件到OSG紋理中,並把紋理渲染在模型上,比如實現一個立體廣告牌。

3、模型縮放后光照結果錯誤,是什么原因?

答:OpenGL的放縮矩陣會同時變換模型的法線,進而影響光照效果,因此放大時可能造成模型表面光照過強,需要打開GL_NORMALIZE。

在OSG中使用stateset->setMode( GL_NORMALIZE, osg::StateAttribute::ON );

4、OSG中如何打開雙面光照

答:使用osg::LightModel渲染屬性

5、OSG中可以播放GIF動畫么?

答:可以,使用OSG提供的gif插件,可以讀取動態GIF圖片,並通過設置為模型紋理來渲染該圖片。通過GIF插件讀取GIF圖片返回的對象派生自osg::ImageStream,因此,可以使用paly等接口控制動畫播放。

GIF插件提供了輕量級的動畫紋理播放方式,較quicktime等視頻播放插件更適合一些簡單的應用場合。

另外,OSG還提供osg::ImageSequence類,可以通過讀入多個靜態圖片形成一個sequence,並通過ImageStream接口函數控制多張圖片的連續播放。

6、什么是烘培,在OSG中怎樣實現烘培?

答:烘培又叫紋理烘培,是指通過每幀預渲染一副場景到指定紋理上,實現模型貼圖的動態效果。如水面倒影、鏡子、倒計時牌上跳動的文字等效果的實現,都可以使用紋理烘培技術。

在OSG中實現紋理烘培是非常容易的,大致步驟如下:

創建紋理對象,設置紋理的大小、像素格式,並把紋理對象綁定到模型;

創建烘培用的相機,指定渲染順序為PRE_RENDER,指定實現方式為FRAME_BUFFER_OBJECT,並把相機的顏色緩沖區綁定到紋理對象;

把要渲染到紋理上的場景加入相機的下級;

把相機加入場景。

具體例子可參考examples\osgprerender或demos\RTT

7、為什么我的OSG窗口看到的圓球是扁的?

答:這是因為投影矩陣的設置有問題,一般情況下應該根據視口實際的寬高比來設置投影矩陣,如視口寬、高分別為width和height,則設置相機投影矩陣為camera->setProjectionMatrixAsPerspective(30, (double)width/height, 1.0f,10000.0f);

 如果沒有按實際視口寬高來設置投影矩陣,就會出現畫面被壓縮或拉伸的效果。

當窗口大小發生變化時,系統通過GraphicsContext對象自動響應WM_SIZE消息,對該GraphicsContext對象相關聯的所有相機(通過調用osg::Camera::setGraphicsContext將相機與GraphicsContext關聯)自動更新視口和投影矩陣,更新投影矩陣的方法為根據寬高比的改變來等比縮放投影矩陣。

可以通過osg::Camera::setProjectionResizePolicy設置相機在窗口大小發生變化時重置投影矩陣的策略,設置為FIXED則不會自動重置投影矩陣,缺省設置為HORIZONTAL。

對於HUD相機,由於其使用正交投影矩陣,不能通過上述縮放的方式修改投影矩陣(正交投影矩陣不但和寬高比有關,還和寬高值有關)。可以自己實現一個GUIEventHandler響應RESIZE事件,根據當前主視口寬高重設HUD相機的視口和投影矩陣。

8、什么是VBO,什么是DisplayList?

答:VBO和DisplayList是OpenGL提供的兩種用於提高渲染效率的技術。

VBO(Vertex Buffer Object)-頂點緩沖區對象,DisplayList-顯示列表。

在使用VBO時,如果修改頂點數組內容,則需要調用頂點數組的dirty()函數應用修改;使用DisplayList時,如果修改頂點數組內容,則需要調用dirtyDisplayList()來應用修改。

OSG中缺省使用顯示列表而不使用VBO。

9、OSG中分頁數據庫線程、渲染線程和篩選線程是在什么時候退出的?

答:1.osgViewer::Viewer對象析構時會調用stopThreading同步退出渲染和篩選線程,並調用DatabasePager::cancel通知分頁數據庫線程退出。
       2.在收到WM_CLOSE消息時會調用stopThreading同步退渲染和篩選線程。
       3.可以在需要的時候手動調用stopThreading同步退出渲染和篩選線程。

10、OSG處理事件的時機和順序是怎樣的?

答:OSG在Viewer::eventTraversal函數中處理輸入事件,eventTraversal在幀循環的更新遍歷和渲染遍歷之前被調用。
       eventTraversal中事件處理的順序為:
             1.為本幀每一個事件遍歷場景樹,調用Node、Drawable、StateSet對象的事件處理回調處理事件。
             2.為本幀每一個事件遍歷Viewer的事件處理器(GUIEventHandler)隊列,調用事件處理器處理事件。
             3.為本幀每一個事件,調用Viewer的相機操作器(CameraManipulator)處理事件。

11、Switch(開關)節點的作用是什么?

答:Switch節點繼承自Group節點,對應於childLis有一個boolList,為每一個子節點保存了一個開關值,當子節點開關關閉時,保證子節點不會被訪問類型為Active子節點的訪問器訪問到。
當子節點開關關閉時,子節點不參與包圍盒計算。

12、NodeMask、TraversalMask的作用是什么?

答:NodeMask(32位無符號整形)作為Node類的屬性,用於限定節點是否能被指定的節點訪問器訪問。缺省值為0xffffffff。
TraversalMask(還有OverrideMask)作為節點訪問器的屬性,用於限定節點訪問器能夠訪問哪些節點。缺省值為0xffffffff。
節點是否能被訪問器訪問取決於:TraversalMask & ( OverrideMask | NodeMask )

13、osg::ColorMask的作用是什么?

答:ColorMask封裝了glColorMask函數的功能,用於設置對顏色緩沖區的寫掩碼,即設置是否對R、G、B、A位執行寫入操作。
在只需要寫深度緩沖或模板緩沖,而不實際繪制物體時,可以使用ColorMask並設置對RGBA的寫入掩碼均為false。

14、怎樣布局屏幕元素(文字、圖片等)

答:屏幕元素一般使用HUD的方式(即正交投影)渲染,在osg中可以定義一個正交投影的相機,把屏幕元素作為子節點添加給這個HUD相機進行渲染。元素的布局和縮放,一般有兩種處理方式:
一、 按視口實際大小布局,同時跟蹤輸出窗口的大小變化,並按窗口實際大小更新HUD相機的投影矩陣和視口。這種方式不但要動態更新相機的投影矩陣和視口,而且要自己編寫代碼根據視口大小變化動態更新屏幕元素的位置和大小,如按指定的對齊方式更新位置、按指定的尺寸比例更新大小。也可以只更新位置不更新大小,這樣得到的效果就是屏幕元素的大小不隨窗口縮放。
二、 按指定的固定大小布局,同時設置HUD相機的投影矩陣為以相同寬高計算的固定值,跟蹤輸出窗口大小變化,按窗口實際大小更新HUD相機的視口。這種方式只需要編寫代碼更新相機的視口即可,而屏幕元素的大小和位置始終按初始的固定視口大小計算,不需隨窗口變化做調整。這樣得到的效果就是屏幕元素的大小和布局與窗口等比縮放。

15、setAttribute與setAttributeAndModes的異同

答:setAttribute用於設置渲染屬性和屬性的覆蓋模式,第二個參數的有效值只有OVERRIDE和PROTECTED的組合,不影響屬性狀態的開關(設置ON/OFF是無效的)!
    setAttributeAndModes設置渲染屬性和覆蓋模式的同時,也會設置屬性狀態的開關。
    setAttribute用於只需設置渲染屬性而不改變狀態的場合,具體是否打開該狀態取決於子節點的設置。

16、OSG場景篩選中有哪些優化效率的算法
答:OSG場景篩選主要用到的篩選方法有:視景體篩選、最小像素篩選和遮擋篩選。其中視景體篩選是最基本和最常用的篩選方法,它的算法是:使用構成視景體的各個面與節點包圍盒求交,如果節點在某個面以外,則剔除掉該節點及其子節點;如果節點完全在某個面以內,則該節點的所有子節點在進行篩選計算的時候不需要再與這個面求交(子節點必然也完全在這個面以內)。鑒於這種篩選實現,恰當使用樹形結構場景圖組織場景節點,能夠提高篩選效率。

17、我在MFC的Static控件中使用OSG渲染,但不能響應鼠標事件是為什么?
答:這完全是MFC控件使用的問題,要使對話框中的Static控件接收鼠標消息,需要把Static控件屬性的Notify設置為True。


18、OSG渲染排序是怎么做的,有哪些接口可以用來控制渲染順序?
答:OSG通過場景揀選(cull)生成一棵由RenderStage(根節點)、RenderBin(分支節點)和RenderLeaf(渲染葉)構成的渲染樹,同時生成一棵由StateGraph構成的渲染狀態樹,最終的渲染操作通過渲染樹進行,渲染的順序為:
 RenderStage::draw
                          |
 RenderStage::drawPreRenderStages
                          |
 RenderStage::drawInner ------------------------------------------- RenderBin::draw
                          |                                                                                          |
 RenderStage::drawPostRenderStages                                   BinNum小於0的子Bin(按BinNum升序) 
                                                                                                                     |
                                                                                                 本Bin的渲染葉列表(排序的)
                                                                                                                     |
                                                                                                 本Bin下掛的所有StateGraph中的渲染葉
                                                                                                                      |
                                                                                                   其他的子Bin(按BinNum升序)
在揀選過程中,通過揀選測試的Drawable對象被添加到當前StateGraph對象的渲染葉列表中,而StateGraph則被當前RenderBin對象引用,而最終渲染時,部分渲染葉也是通過RenderBin引用的StateGraph對象找到並渲染的,其他渲染葉(對應RenderBin的排序模式為FRONT_TO_BACK/BACK_TO_FRONT/TRAVERSAL_ORDER的)被轉移到RenderBin的渲染葉列表中排序然后渲染。

我們可以通過StateSet的BinNum和BinName設置來控制對應節點的渲染順序。
1)BinName為"RenderBin"、"StateSortedBin"的缺省排序方式為SORT_BY_STATE(目前實現為不排序)
   BinName為"DepthSortedBin"的缺省排序方式為SORT_BACK_TO_FRONT(由遠到近,用於半透物體的alpha混合)
   BinName為"TraversalOrderBin"的缺省排序方式為TRAVERSAL_ORDER(即按遍歷到的先后順序排序)。
2)BinNum小的靠前渲染
3)setNestRenderBins設置RenderBin是否允許嵌套,為true時新的RenderBin被添加為當前RenderBin的子節點,為false時新的RenderBin被添加為RenderStage(根節點)的子節點。

19、OSG對組合鍵是怎樣映射的?
答:由於Win32 API的特點,OSG不得不將Ctrl+letter變換到了{1,..,26},也就是說,CTRL+a的getKey()為1,而CTRL+z的getKey()為26;Shift+a~z被映射到大寫的'A'~'Z'。

20、為什么OSG自動為我的紋理對象創建了mipmap?
答:當紋理過濾方式min_filter設置為基於mipmap的4種之一時,OSG將自動為非mipmap貼圖紋理對象創建mipmap。min_filter的缺省值是LINEAR_MIPMAP_LINEAR,因此如果未顯式設置紋理過濾方式的話,即會啟用自動創建mipmap的功能。

21、Texture::setUnRefImageDataAfterApply的作用?
答:當該值設置為true時,OSG在應用過該紋理對象后(apply),自動釋放其對Image對象的引用,以減少內存占用。

22、osgDB::SharedStateManager的作用?
答:SharedStateManager用於對系統中的StateSet、Texture對象執行共享優化,即對系統中內容相同的多個Texture對象,只保留一個實例,其他使用引用,以減少內存、顯存的占用,提高渲染效率。使用方式為,為新加載或創建的節點對象調用osgDB::Registry()->getOrCreateSharedStateManager()->share函數。

 23、如何打開分頁數據庫的預編譯功能?
答:需要做兩件事,1)設置osg::DisplaySettings::instance()->setCompileContextsHint(true),使Viewer在realize時創建后台GC用於預編譯操作;2)調用osgDB::DabasePager::setDoPreCompile(true)開啟預編譯功能。

 

 

 

 

http://www.openscenegraph.org/projects/osg

OSG官方網站

http://forum.openscenegraph.org/

OSG官方論壇

http://www.openscenegraph.org/projects/osg/wiki/Downloads/Dependencies

OSG官網上提供的,編譯OSG主要插件的第三方依賴庫,vc7、vc8、vc9、vc10的都有,但是包括庫比較少,只有核心的七八個。

http://www.openscenegraph.org/projects/osg/wiki/Community/PackageMaintainers

OSG官網上提供的,OSG庫的maintainers列表,他們會提供不同版本OSG預編譯庫的下載,也會有第三方依賴庫的下載,如Mattias Helsing在2.8版的OSG發行庫下載目錄中提供了部分第三方依賴庫的下載,包含的庫比上面的多幾個(http://www.openscenegraph.org/downloads/stable_releases/OpenSceneGraph-2.8/binaries/Windows/VisualStudio9/3rdParty_Win32Binaries_vc90sp1.zip)。

http://www.openscenegraph.org/files/dev/OpenSceneGraph-Installer.exe

OSG官網上提供的OSG安裝程序,是在線下載安裝的,包含多個編譯器版本的release和debug文件。

http://www.vis-sim.com/osg/

一個三維仿真資源網站上提供的OSG相關資源列表。


免責聲明!

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



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