11.實(shí)現(xiàn)跟隨節(jié)點(diǎn)的相機(jī)_第1頁
11.實(shí)現(xiàn)跟隨節(jié)點(diǎn)的相機(jī)_第2頁
11.實(shí)現(xiàn)跟隨節(jié)點(diǎn)的相機(jī)_第3頁
11.實(shí)現(xiàn)跟隨節(jié)點(diǎn)的相機(jī)_第4頁
11.實(shí)現(xiàn)跟隨節(jié)點(diǎn)的相機(jī)_第5頁
已閱讀5頁,還剩45頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、osg開源教程整理:榮明、王偉北 京 2008年4月序第一次接觸osg是在2001年,當(dāng)時(shí)開源社區(qū)剛剛興起,還沒有現(xiàn)在這么火。下載了osg源碼,但是在看了幾個(gè)demo之后,感覺沒有什么特別之處。時(shí)隔七年之后,我再次將目光投向osg,發(fā)現(xiàn)osg確實(shí)有其獨(dú)到之處,很多3d效果已經(jīng)不弱于甚至超過商業(yè)軟件,有感于開源力量的巨大。但是,與當(dāng)前主流3d商業(yè)軟件如vega、vegaprime、vtree、performer等相比,開源軟件的缺點(diǎn)也很明顯,其中文檔缺乏可謂其致命弱點(diǎn)之一。開發(fā)者只能從浩瀚的源碼中,進(jìn)行編程的學(xué)習(xí),效率不高。osg組織也意識到這一點(diǎn),不斷推出一些官方教程,網(wǎng)絡(luò)上有很多osg愛好者

2、發(fā)布的心得和教程。我收集、整理了許多學(xué)習(xí)資料,其中美國海軍研究生院發(fā)布的osg教程非常好,可作為osg的官方教程的一個(gè)很好補(bǔ)充。它共有十一個(gè)專題,結(jié)合例子程序,一步步教你如何進(jìn)行osg的開發(fā)。我將其編輯成一個(gè)較為完善的教材,供大家學(xué)習(xí)。在教材整理過程中,王偉調(diào)試了源程序,對該書編輯和修訂做了大量的工作;實(shí)驗(yàn)室的學(xué)生楊宇蒙、馮銳、章仕鋒、李永川和李益強(qiáng)閱讀了本書,并提出了寶貴的修改意見,在此一并表示感謝。希望這本小冊子能對大家學(xué)習(xí)osg編程起到一定的幫助作用。謝謝大家閱讀本書! 榮 明二oo八年四月于崔春園email:rong_ming(本書的資料全部來自互聯(lián)網(wǎng),僅供個(gè)人學(xué)習(xí)交流使用。感謝竹林小

3、舍、array翻譯了navy的教程。)45目錄1.使用open scene graph幾何11.1背景11.2代碼12.使用stateset產(chǎn)生有紋理的幾何體42.1本章目標(biāo)42.2背景42.3加載紋理,生成狀態(tài)集合并將他們附加到節(jié)點(diǎn)上63.使用shape,改變state83.1本章目標(biāo)83.2使用shape類83.3設(shè)置狀態(tài)94.更多的stateset104.1stateset如何工作104.2例子及代碼105.從文件中加載模型并放入到場景中125.1本章目標(biāo)125.2加載幾何模型并加入到場景中126.osg text、hud、renderbins156.1本章目標(biāo)156.2摘要156.3代

4、碼157.搜索并控制開關(guān)和dof(自由度)節(jié)點(diǎn)(finding and manipulating a switch and dof node)207.1搜索場景圖形中的一個(gè)有名節(jié)點(diǎn)207.2按照“訪問器”模式搜索有名節(jié)點(diǎn)228.使用更新回調(diào)來更改模型268.1本章目標(biāo)268.2回調(diào)概覽268.3創(chuàng)建一個(gè)更新回調(diào)269.處理鍵盤輸入299.1本章目標(biāo)299.2 gui(圖形用戶接口)事件處理器:299.3簡單的鍵盤接口類309.4使用鍵盤接口類329.5處理鍵盤輸入實(shí)現(xiàn)更新回調(diào)329.5.1本節(jié)目標(biāo)329.5.2問題的提出329.5.3解決方案3310.使用自定義矩陣來放置相機(jī)(position

5、ing a camera with a user-defined matrix)3610.1本章目標(biāo)3610.2設(shè)置矩陣的方向和位置3610.3聲明一個(gè)用于設(shè)置相機(jī)的矩陣3710.4使用矩陣設(shè)置視口攝相機(jī)3811. 實(shí)現(xiàn)跟隨節(jié)點(diǎn)的相機(jī)3811.1本章目標(biāo)3811.2概述3911.3實(shí)現(xiàn)3911.4環(huán)繞(始終指向)場景中節(jié)點(diǎn)的相機(jī)4211.4.1本節(jié)目標(biāo)4211.4.2實(shí)現(xiàn)431.使用open scene graph幾何本節(jié)涵蓋了生成基本幾何形狀的一些方法。生成幾何物體的方法有這么幾種:在最底層對opengl基本幾何進(jìn)行松散的包裝,中級是使用open scene graph的基本形狀,以及更高級

6、一些的從文件讀取。這篇教程涵蓋的是最低層的。這種方法彈性最大但最費(fèi)力。通常在scene graph級別,幾何形狀是從文件加載的。文件加載器完成了跟蹤頂點(diǎn)的大部分工作。1.1背景對一下幾個(gè)類的簡單解釋:geode類: geode類繼承自node類。在一個(gè)scene graph中,node(當(dāng)然包含geode)可以作為葉子節(jié)點(diǎn)。geode實(shí)例可以有多個(gè)相關(guān)的drawable。drawable類層次: 基類drawable是一個(gè)有六個(gè)具體子類的抽象類。 geometry類可以直接有vertex和vertex數(shù)據(jù),或者任意個(gè)primitiveset實(shí)例。 vertex和vertex屬性數(shù)據(jù)(顏色、法線

7、、紋理坐標(biāo))存放在數(shù)組中。既然多個(gè)頂點(diǎn)可以共享相同的顏色、法線或紋理坐標(biāo),那么數(shù)組索引就可以用來將頂點(diǎn)數(shù)組映射到顏色、法線、或紋理坐標(biāo)數(shù)組。primitiveset類: 這個(gè)類松散的包裝了opengl的基本圖形points,lines,line_strip,line_loop,.,polygon. 1.2代碼以下這節(jié)代碼安裝了一個(gè)viewer來觀察我們創(chuàng)建的場景,一個(gè)group實(shí)例作為scene graph的根節(jié)點(diǎn),一個(gè)幾何節(jié)點(diǎn)(geode)來收集drawable,和一個(gè)geometry實(shí)例來關(guān)聯(lián)頂點(diǎn)和頂點(diǎn)數(shù)據(jù)。(這個(gè)例子中渲染的形狀是一個(gè)四面體).int main() .osgproduce

8、r:viewer viewer; osg:group* root = new osg:group(); osg:geode* pyramidgeode = new osg:geode(); osg:geometry* pyramidgeometry = new osg:geometry();下一步,需要將錐體geometry和錐體geode關(guān)聯(lián)起來,并將pyramid geode加到scene graph的根節(jié)點(diǎn)上。pyramidgeode-adddrawable(pyramidgeometry); root-addchild(pyramidgeode);聲明一個(gè)頂點(diǎn)數(shù)組。每個(gè)頂點(diǎn)由一個(gè)三元組

9、表示vec3類的實(shí)例。這些三元組用osg:vec3array類的實(shí)例存貯。既然osg:vec3array繼承自stl的vector類,那么我們就可以使用push_back方法來添加數(shù)組成員。push_back將元素加到向量的尾端,因此第一個(gè)元素的索引是0,第二個(gè)是1,依此類推。 使用z軸向上的右手坐標(biāo)系系統(tǒng),下面的0.4數(shù)組元素代表著產(chǎn)生一個(gè)簡單錐體所需的5個(gè)點(diǎn)。osg:vec3array* pyramidvertices = new osg:vec3array; pyramidvertices-push_back( osg:vec3( 0, 0, 0) ); / front left pyr

10、amidvertices-push_back( osg:vec3(10, 0, 0) ); / front right pyramidvertices-push_back( osg:vec3(10,10, 0) ); / back right pyramidvertices-push_back( osg:vec3( 0,10, 0) ); / back left pyramidvertices-push_back( osg:vec3( 5, 5,10) ); / peak 將這個(gè)頂點(diǎn)集合和與我們加到場景中的geode相關(guān)的geometry關(guān)聯(lián)起來。pyramidgeometry-setvert

11、exarray( pyramidvertices );下一步,產(chǎn)生一個(gè)基本集合并將其加入到pyramid geometry中。使用pyramid的前四個(gè)點(diǎn)通過drawelementsuint類的實(shí)例來定義基座。這個(gè)類也繼承自stl的vector,所以push_back方法會順序添加元素。為了保證合適的背面剔除,頂點(diǎn)的順序應(yīng)當(dāng)是逆時(shí)針方向的。構(gòu)造器的參數(shù)是基本的枚舉類型(和opengl的基本枚舉類型一致),和起始的頂點(diǎn)數(shù)組索引。osg:drawelementsuint* pyramidbase = new osg:drawelementsuint(osg:primitiveset:quads,

12、0); pyramidbase-push_back(3); pyramidbase-push_back(2); pyramidbase-push_back(1); pyramidbase-push_back(0); pyramidgeometry-addprimitiveset(pyramidbase);對每個(gè)面重復(fù)相同的動(dòng)作。頂點(diǎn)仍要按逆時(shí)針方向指定。osg:drawelementsuint* pyramidfaceone = new osg:drawelementsuint(osg:primitiveset:triangles, 0); pyramidfaceone-push_back(0

13、); pyramidfaceone-push_back(1); pyramidfaceone-push_back(4); pyramidgeometry-addprimitiveset(pyramidfaceone); osg:drawelementsuint* pyramidfacetwo = new osg:drawelementsuint(osg:primitiveset:triangles, 0); pyramidfacetwo-push_back(1); pyramidfacetwo-push_back(2); pyramidfacetwo-push_back(4); pyramid

14、geometry-addprimitiveset(pyramidfacetwo); osg:drawelementsuint* pyramidfacethree = new osg:drawelementsuint(osg:primitiveset:triangles, 0); pyramidfacethree-push_back(2); pyramidfacethree-push_back(3); pyramidfacethree-push_back(4); pyramidgeometry-addprimitiveset(pyramidfacethree); osg:drawelements

15、uint* pyramidfacefour = new osg:drawelementsuint(osg:primitiveset:triangles, 0); pyramidfacefour-push_back(3); pyramidfacefour-push_back(0); pyramidfacefour-push_back(4); pyramidgeometry-addprimitiveset(pyramidfacefour)聲明并加載一個(gè)vec4為元素的數(shù)組來存儲顏色。osg:vec4array* colors = new osg:vec4array; colors-push_bac

16、k(osg:vec4(1.0f, 0.0f, 0.0f, 1.0f) ); /index 0 red colors-push_back(osg:vec4(0.0f, 1.0f, 0.0f, 1.0f) ); /index 1 green colors-push_back(osg:vec4(0.0f, 0.0f, 1.0f, 1.0f) ); /index 2 blue colors-push_back(osg:vec4(1.0f, 1.0f, 1.0f, 1.0f) ); /index 3 white聲明的這個(gè)變量可以將頂點(diǎn)數(shù)組元素和顏色數(shù)組元素匹配起來。這個(gè)容器的元素?cái)?shù)應(yīng)當(dāng)和頂點(diǎn)數(shù)一致。這個(gè)

17、容器是頂點(diǎn)數(shù)組和顏色數(shù)組的連接。這個(gè)索引數(shù)組中的條目就對應(yīng)著頂點(diǎn)數(shù)組中的元素。他們的值就是顏色數(shù)組中的索引。頂點(diǎn)數(shù)組元素與normal和紋理坐標(biāo)數(shù)組的匹配也是遵循這種模式。 注意,這種情況下,我們將5個(gè)頂點(diǎn)指定4種顏色。頂點(diǎn)數(shù)組的0和4元素都被指定為顏色數(shù)組的0元素。osg:templateindexarray *colorindexarray; colorindexarray = new osg:templateindexarray; colorindexarray-push_back(0); / vertex 0 assigned color array element 0 colorin

18、dexarray-push_back(1); / vertex 1 assigned color array element 1 colorindexarray-push_back(2); / vertex 2 assigned color array element 2 colorindexarray-push_back(3); / vertex 3 assigned color array element 3 colorindexarray-push_back(0); / vertex 4 assigned color array element 0下一步,將顏色數(shù)組和geometry關(guān)聯(lián)

19、起來,將上面產(chǎn)生的顏色索引指定給geometry,設(shè)定綁定模式為_per_vertex。pyramidgeometry-setcolorarray(colors); pyramidgeometry-setcolorindices(colorindexarray); pyramidgeometry-setcolorbinding(osg:geometry:bind_per_vertex); osg:vec2array* texcoords = new osg:vec2array(5); (*texcoords)0.set(0.00f,0.0f); (*texcoords)1.set(0.25f,

20、0.0f); (*texcoords)2.set(0.50f,0.0f); (*texcoords)3.set(0.75f,0.0f); (*texcoords)4.set(0.50f,1.0f); pyramidgeometry-settexcoordarray(0,texcoords);注:一下部分可能錯(cuò)誤。/ declare and initialize a transform node. osg:positionattitudetransform* pyramidtwoxform = new osg:positionattitudetransform(); / use the addc

21、hild method of the osg:group class to / add the transform as a child of the root node and the / pyramid node as a child of the transform. root-addchild(pyramidtwoxform); pyramidtwoxform-addchild(pyramidgeode); / declare and initialize a vec3 instance to change the / position of the tank model in the

22、 scene osg:vec3 pyramidtwoposition(15,0,0); pyramidtwoxform-setposition( pyramidtwoposition );既然我們生成了一個(gè)geometry節(jié)點(diǎn)并將它加到了場景中,我們就可以重用這個(gè)geometry。例如,如果我們想讓另一個(gè)pyramid在第一個(gè)的右側(cè)15個(gè)單位處,我們就可以在我們的scene graph中將這個(gè)geode加到transform節(jié)點(diǎn)的子節(jié)點(diǎn)上。 最后一步,建立并進(jìn)入一個(gè)仿真循環(huán)。viewer.setupviewer(osgproducer:viewer:standard_settings); vi

23、ewer.setscenedata( root ); viewer.realize(); while( !viewer.done() ) viewer.sync(); viewer.update(); viewer.frame(); 2.使用stateset產(chǎn)生有紋理的幾何體2.1本章目標(biāo)為教程1中介紹的由opengl基本繪制單位定義的幾何體添加紋理。2.2背景前一節(jié)教程介紹了包含由opengl基本單位產(chǎn)生的基本形狀的視景。本節(jié)講解如何為這些形狀添加紋理。為了使代碼更方便使用,我們將pyramid的代碼放到一個(gè)函數(shù)中,產(chǎn)生geode并返回它的指針。下面的代碼來自教程1。osg:geode* c

24、reatepyramid() osg:geode* pyramidgeode = new osg:geode(); osg:geometry* pyramidgeometry = new osg:geometry(); pyramidgeode-adddrawable(pyramidgeometry); / specify the vertices: osg:vec3array* pyramidvertices = new osg:vec3array; pyramidvertices-push_back( osg:vec3(0, 0, 0) ); / front left pyramidver

25、tices-push_back( osg:vec3(2, 0, 0) ); / front right pyramidvertices-push_back( osg:vec3(2, 2, 0) ); / back right pyramidvertices-push_back( osg:vec3( 0,2, 0) ); / back left pyramidvertices-push_back( osg:vec3( 1, 1,2) ); / peak / associate this set of vertices with the geometry associated with the /

26、 geode we added to the scene. pyramidgeometry-setvertexarray( pyramidvertices ); / create a quad primitive for the base by specifying the / vertices from our vertex list that make up this quad: osg:drawelementsuint* pyramidbase = new osg:drawelementsuint(osg:primitiveset:quads, 0); pyramidbase-push_

27、back(3); pyramidbase-push_back(2); pyramidbase-push_back(1); pyramidbase-push_back(0); /add this primitive to the geometry: pyramidgeometry-addprimitiveset(pyramidbase); / code to create other faces goes here! / (removed to save space, see tutorial two) osg:vec4array* colors = new osg:vec4array; col

28、ors-push_back(osg:vec4(1.0f, 0.0f, 0.0f, 1.0f) ); /index 0 red colors-push_back(osg:vec4(0.0f, 1.0f, 0.0f, 1.0f) ); /index 1 green colors-push_back(osg:vec4(0.0f, 0.0f, 1.0f, 1.0f) ); /index 2 blue colors-push_back(osg:vec4(1.0f, 1.0f, 1.0f, 1.0f) ); /index 3 white osg:templateindexarray *colorindex

29、array; colorindexarray = new osg:templateindexarray; colorindexarray-push_back(0); / vertex 0 assigned color array element 0 colorindexarray-push_back(1); / vertex 1 assigned color array element 1 colorindexarray-push_back(2); / vertex 2 assigned color array element 2 colorindexarray-push_back(3); /

30、 vertex 3 assigned color array element 3 colorindexarray-push_back(0); / vertex 4 assigned color array element 0 pyramidgeometry-setcolorarray(colors); pyramidgeometry-setcolorindices(colorindexarray); pyramidgeometry-setcolorbinding(osg:geometry:bind_per_vertex); / since the mapping from vertices t

31、o texture coordinates is 1:1, / we dont need to use an index array to map vertices to texture / coordinates. we can do it directly with the settexcoordarray / method of the geometry class. / this method takes a variable that is an array of two dimensional / vectors (osg:vec2). this variable needs to

32、 have the same / number of elements as our geometry has vertices. each array element / defines the texture coordinate for the cooresponding vertex in the / vertex array. osg:vec2array* texcoords = new osg:vec2array(5); (*texcoords)0.set(0.00f,0.0f); / tex coord for vertex 0 (*texcoords)1.set(0.25f,0

33、.0f); / tex coord for vertex 1 (*texcoords)2.set(0.50f,0.0f); / (*texcoords)3.set(0.75f,0.0f); / (*texcoords)4.set(0.50f,1.0f); / pyramidgeometry-settexcoordarray(0,texcoords); return pyramidgeode; 2.3加載紋理,生成狀態(tài)集合并將他們附加到節(jié)點(diǎn)上渲染基本單位的方法是使用stateset。這節(jié)代碼演示了怎樣從文件中加載紋理,產(chǎn)生此紋理起作用的一個(gè)stateset,并將這個(gè)stateset附加到場景中的

34、一個(gè)節(jié)點(diǎn)上。前面開始的代碼和上一節(jié)教程中的一樣,初始化一個(gè)viewer并建立有一個(gè)pyramid的場景。int main() osgproducer:viewer viewer; / declare a group to act as root node of a scene: osg:group* root = new osg:group(); osg:geode* pyramidgeode = createpyramid(); root-addchild(pyramidgeode);現(xiàn)在,準(zhǔn)備加紋理。這里我們會聲明一個(gè)紋理實(shí)例并將它的數(shù)據(jù)不一致性設(shè)為dynamic。(如果不把紋理聲明為dy

35、namic,osg的一些優(yōu)化程序會刪除它。)這個(gè)texture類包裝了opengl紋理模式(wrap,filter,等等)和一個(gè)osg:image。下面的代碼說明了如何從文件里讀取osg:image實(shí)例并把這個(gè)圖像和紋理關(guān)聯(lián)起來。osg:texture2d* kln89facetexture = new osg:texture2d; / protect from being optimized away as static state: kln89facetexture-setdatavariance(osg:object:dynamic); / load an image by readin

36、g a file: osg:image* klnface = osgdb:readimagefile(kln89faceb.tga); if (!klnface) std:cout couldnt find texture, quiting. setimage(klnface);紋理可以和渲染stateset關(guān)聯(lián)起來。下一步就產(chǎn)生一個(gè)stateset,關(guān)聯(lián)并啟動(dòng)我們的紋理,并將這個(gè)stateset附加到我們的geometry上。/ create a new stateset with default settings: osg:stateset* stateone = new osg:stat

37、eset(); / assign texture unit 0 of our new stateset to the texture / we just created and enable the texture. stateone-settextureattributeandmodes(0,kln89facetexture,osg:stateattribute:on); / associate this state set with the geode that contains / the pyramid: pyramidgeode-setstateset(stateone);最后一步是

38、仿真循環(huán):/the final step is to set up and enter a simulation loop. viewer.setupviewer(osgproducer:viewer:standard_settings); viewer.setscenedata( root ); viewer.realize(); while( !viewer.done() ) viewer.sync(); viewer.update(); viewer.frame(); return 0; 3.使用shape,改變state3.1本章目標(biāo)用osg:shape實(shí)例構(gòu)建場景。使用osg:sta

39、teset控制shape的渲染。3.2使用shape類shape類是所有形狀類別的基類。shape既可用于剪裁和碰撞檢測也可用于定義程序性地產(chǎn)生幾何體的那些基本形狀。下面的類繼承自shape類: trianglemesh sphere infiniteplane heightfield cylinder cone compositeshape box 為了使這些形狀可以被渲染,我們需要把他們和drawable類的實(shí)例關(guān)聯(lián)起來。shapedrawable類提供了這樣的功能。這個(gè)類繼承自drawable并允許我們把shape實(shí)例附加到可以被渲染的東西上。既然shapedrawable類繼承自dra

40、wable,shapdrawable實(shí)例就可以被加到geode類實(shí)例上。下面的步驟演示了將一個(gè)單位立方體加到空場景中時(shí)是如何做到這些的。/ declare a group to act as root node of a scene: osg:group* root = new osg:group(); / declare a box class (derived from shape class) instance / this constructor takes an osg:vec3 to define the center / and a float to define the hei

41、ght, width and depth. / (an overloaded constructor allows you to specify unique / height, width and height values.) osg:box* unitcube = new osg:box( osg:vec3(0,0,0), 1.0f); / declare an instance of the shape drawable class and initialize / it with the unitcube shape we created above. / this class is

42、 derived from drawable so instances of this / class can be added to geode instances. osg:shapedrawable* unitcubedrawable = new osg:shapedrawable(unitcube); / declare a instance of the geode class: osg:geode* basicshapesgeode = new osg:geode(); / add the unit cube drawable to the geode: basicshapesge

43、ode-adddrawable(unitcubedrawable); / add the goede to the scene: root-addchild(basicshapesgeode); 產(chǎn)生一個(gè)球體和上面的代碼基本相似。沒有太多的注釋的代碼看起來是這個(gè)樣子:/ create a sphere centered at the origin, unit radius: osg:sphere* unitsphere = new osg:sphere( osg:vec3(0,0,0), 1.0); osg:shapedrawable* unitspheredrawable=new osg:s

44、hapedrawable(unitsphere); 現(xiàn)在,我們可以使用transform節(jié)點(diǎn)將這個(gè)球體加到場景中,以便讓它離開原點(diǎn)。unitspheredrawable不能直接添加到場景中(因?yàn)樗皇抢^承自node類),所以我們需要一個(gè)新的geode以便添加它。osg:positionattitudetransform* spherexform = new osg:positionattitudetransform(); spherexform-setposition(osg:vec3(2.5,0,0); osg:geode* unitspheregeode = new osg:geode()

45、; root-addchild(spherexform); spherexform-addchild(unitspheregeode); unitspheregeode-adddrawable(unitspheredrawable);3.3設(shè)置狀態(tài)前面的教程講解了如何生成紋理,將其指定為從文件加載的圖像,生成一個(gè)帶紋理的stateset。下面的代碼建立了兩個(gè)狀態(tài)集合一個(gè)是blend紋理模式,另一個(gè)是decal紋理模式。blend模式:/ declare a state set for blend texture mode osg:stateset* blendstateset = new os

46、g:stateset(); / declare a texenv instance, set the mode to blend osg:texenv* blendtexenv = new osg:texenv; blendtexenv-setmode(osg:texenv:blend); / turn the attribute of texture 0 - the texture we loaded above - on blendstateset-settextureattributeandmodes(0,kln89facetexture,osg:stateattribute:on);

47、/ set the texture texture environment for texture 0 to the / texture envirnoment we declared above: blendstateset-settextureattribute(0,blendtexenv); 重復(fù)這些步驟,產(chǎn)生decal紋理模式的狀態(tài)集合。osg:stateset* decalstateset = new osg:stateset();osg:texenv* decaltexenv = new osg:texenv(); decaltexenv-setmode(osg:texenv:de

48、cal); decalstateset-settextureattributeandmodes(0,kln89facetexture,osg:stateattribute:on); decalstateset-settextureattribute(0,decaltexenv);產(chǎn)生了狀態(tài)集合后我們就可以把它們應(yīng)用在場景中的節(jié)點(diǎn)上。在scene graph的繪制遍歷(root-leaf)中狀態(tài)是積累的。除非這個(gè)節(jié)點(diǎn)有一個(gè)它自己的狀態(tài),否則它會繼承其父節(jié)點(diǎn)的狀態(tài)。(如果一個(gè)節(jié)點(diǎn)有一個(gè)以上的父節(jié)點(diǎn),它會使用一個(gè)以上的狀態(tài)渲染。)root-setstateset(blendstateset); un

49、itspheregeode-setstateset(decalstateset); 最后一步是進(jìn)入仿真循環(huán)。viewer.setupviewer(osgproducer:viewer:standard_settings); viewer.setscenedata( root ); viewer.realize(); while( !viewer.done() ) viewer.sync(); viewer.update(); viewer.frame(); return 0;4.更多的stateset4.1stateset如何工作場景圖管理器遍歷scene graph,決定哪些幾何體需要送到圖

50、形管道渲染。在遍歷的過程中,場景圖管理器也搜集幾何體如何被渲染的信息。這些信息存在osg:stateset實(shí)例中。stateset包含opengl的屬性/數(shù)值對列表。這些stateset可以和scenegraph中的節(jié)點(diǎn)關(guān)聯(lián)起來。在預(yù)渲染的遍歷中,stateset從根節(jié)點(diǎn)到葉子節(jié)點(diǎn)是積累的。一個(gè)節(jié)點(diǎn)的沒有變化的狀態(tài)屬性也是簡單的遺傳自父節(jié)點(diǎn)。 幾個(gè)附加的特性允許更多的控制和彈性。一個(gè)狀態(tài)的屬性值可以被設(shè)為override。這意味著這個(gè)節(jié)點(diǎn)的所有孩子節(jié)點(diǎn)不管其屬性值是什么會遺傳其父節(jié)點(diǎn)的屬性值。override意味著可以被覆蓋。如果一個(gè)孩子節(jié)點(diǎn)把那個(gè)屬性設(shè)為protected,那么它就可以設(shè)置自

51、己的屬性值,而不用理會父節(jié)點(diǎn)的設(shè)置。4.2例子及代碼下面的場景示范了state如何影響scene graph。根節(jié)點(diǎn)有一個(gè)blend模式紋理的基本狀態(tài)。這個(gè)基本狀態(tài)會被所有子節(jié)點(diǎn)繼承,除非這個(gè)狀態(tài)的參數(shù)改變。根節(jié)點(diǎn)的右子樹就是這樣的。右孩子沒有被指定任何狀態(tài),所以它使用和根節(jié)點(diǎn)一樣的狀態(tài)來渲染。對于節(jié)點(diǎn)6,紋理的混合模式?jīng)]有改變但是使用了一個(gè)新紋理。 根節(jié)點(diǎn)的左子樹的紋理模式被設(shè)為decal。其他的參數(shù)是一樣的,所以它們從根節(jié)點(diǎn)繼承。在節(jié)點(diǎn)3中,fog被打開了并設(shè)置為override。這個(gè)節(jié)點(diǎn)節(jié)點(diǎn)3的左孩子將fog設(shè)為了off。既然它沒有設(shè)置protected并且它父節(jié)點(diǎn)設(shè)置了override

52、,所以就像父節(jié)點(diǎn)一樣fog仍然是on。右孩子4設(shè)置fog屬性值為protected,因此可以覆蓋其父節(jié)點(diǎn)的設(shè)置。a.jpg (86.96 kb)2007-11-23 01:05 pm下面是操作狀態(tài)配置并用節(jié)點(diǎn)將這些狀態(tài)關(guān)聯(lián)起來的代碼。/ set an osg:texenv instances mode to blend, / make this texenv current for texture unit 0 and assign / a valid texture to texture unit 0 blendtexenv-setmode(osg:texenv:blend); stater

53、ootblend-settextureattribute(0,blendtexenv,osg:stateattribute:on); staterootblend-settextureattributeandmodes(0,ocotillotexture,osg:stateattribute:on); / for state five, change the texture associated with texture unit 0 /all other attributes will remain unchanged as inherited from above. / (texture

54、mode will still be blend) statefivedusttexture-settextureattributeandmodes(0,dusttexture,osg:stateattribute:on); / set the mode of an osg:texenv instance to decal /use this mode for stateonedecal. decaltexenv-setmode(osg:texenv:decal); stateonedecal-settextureattribute(0,decaltexenv,osg:stateattribute:on); / for statetwo, turn fog off and set to override. /descendants in this sub-tree will not be able to change fog unless /they set the fog

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論