1. 程式人生 > >OSG 渲染(1) 多檢視的實現方法

OSG 渲染(1) 多檢視的實現方法

一般多檢視、視口在CAD、模擬領域裡用的比較多,遊戲裡用的相對較少。尤其是CAD,要求在多視口內用不同的渲染模式來顯示零件。比如,在單檢視內用多視口方式,分別用著色模式,線框消隱模式來繪製顯示模型。

這裡提到視口,檢視,在不同的軟體中因其定義實現的方式不同,顯得比較混亂,有時兩者不同,有時兩者又等價!按我自己理解,一個視窗內劃分成幾個部分,如果每個子區域包括業務處理邏輯(如事件處理,在子區域內平移、旋轉、縮放物件,其它區域不受影響),這個子區域可以看成是檢視;如果子區域只負責顯示模型,不負責事件處理,該子區域可以看成視口,也就是說將視口看成功能弱於檢視的子顯示區域。這只是個人看法,你完全可以將子顯示區域都定義為視口,例如 AutoCAD。

OSG檢視顯示關鍵幾個類:

osg::View

該類為檢視組織管理最基礎的類,管理主、從相機,光照模式(天光,頭頂光,無光照)。

osgViewer::View : public osg::View, public osgGA::GUIActionAdapter

該類擴充套件了基礎檢視類,加入了場景資料、視窗事件、檢視配置的管理功能,渲染器(Renderer)也在此建立。

osgViewer::ViewerBase

該類為更高層的檢視管類,使檢視具有多執行緒渲染的能力,並管理渲染裝置上下文的初始化,渲染執行緒的管理、排程,檢視更新的三個階段:事件更新過程【eventTraversal()】,狀態更新過程【updateTraversal()】,及渲染更新過程【renderingTraversals()】。

ViewerBase 派生出兩個子類:單檢視視景器 osgViewer::Viewer, 多檢視視景器 osgViewer::CompositeViewer。

osgViewer::Viewer : public ViewerBase, public osgViewer::View

osgViewer::CompositeViewer : public ViewerBase

從上面兩類繼承關係,我們可以看出,osgViewer::CompositeViewer 是沒有渲染能力但具有上下文管理,執行緒排程管理的Viewer 的容器類, 渲染內容的輸出由osgViewer::Viewer 來完成。

從以上檢視相關類的繼承關係可以看出,有三種方式可以實現多檢視:

如果需要子檢視功能完備,能夠處理自己的互動事件,我們就用CompositeViewer 來作為主檢視,再新增Viewer來呈現不同的內容。

如果只需要在檢視內,以不同的視角觀察模型,我們用osgViewer::Viewer 來作為主檢視,在新增不同的slave camera來實現。

如果建立一個主視窗,再建立多個windows視窗,用splitecontainer控制元件分割,每個子視窗用osgViewer::Viewer 做為主檢視,也可以實現多檢視。但這種方式,需要消耗更多的硬體資源,且OpenGL 層面的顯示資料不能公用。


多檢視的實現涉及到幾個細節方面的問題:

模型資料的複用?

物件顯示狀態如何分離?

例如,你在一個檢視內高亮一個物件,因為模型及模型顯示屬性資料是複用的,另一個檢視內相關的物件也會高亮。這在模型顯示屬性在不同檢視內一致時沒有問題,而且是我們想要的顯示效果。但當不同檢視內物件顯示狀態不一致時,就不合適了。例如物件在一個子視窗內是可見的,另一個視窗內是不可見的。

osg 要求當前上下文一定要有一個View, 否則停止渲染。